2015-06-04 1 views
0

У меня есть стандартный javascript-модуль (шаблон), который содержит число частных методов и переменных . Я нахожу, что борюсь с сохранением контекста this, чтобы указать на мой модуль после использования $.each.

Я знаю, что метод jQuery $.each создает закрытие и, следовательно, новый «контекст», однако я хочу продолжать иметь this, ссылаясь на модуль. Я обнаружил, что вызов частной функции моего модуля (initFruit() в образце) с помощью initFruit.call() и передача в self копии this (которая находится в области видимости) работает для этой функции, однако, как только эта функция вызывает еще одна функция, контекст снова потерян.

Я действительно не хочу, чтобы все мои личные функции с помощью .call() все время были просто потому, что я использовал $.each дальше в стеке вызовов, так как я могу использовать $.each, не потеряв исходный контекст?

Fiddle: https://jsfiddle.net/BloodBaz/zz11n5wp/1/

+0

У меня был такой же вопрос давным-давно. Я спросил [вопрос] (http://stackoverflow.com/questions/29983887/this-returning-either-object-or-window-inside-the-same-object), возможно, предоставленные ответы могут вам помочь. –

+0

Спасибо @JeremyThille. Интересно. Ваш пример передает вспомогательную функцию через посредник 'navigator.geolocation.getCurrentPosition', который я не делаю в этом примере. –

ответ

0

В контексте области действия, где вы определяете внутренние затворы, которые заменяют this (например: 90% случаев в частных «методов»), самый простой способ иметь «глобальный масштаб» 'ы Элемент должен определить переменную, обычно self прямо в первой строке вашего основного блока кода. В вашем случае «глобальный» this равен Window, таким образом, вот что я сделал бы, в нескольких словах, заменив «this» на «self», когда вы хотите ссылаться на объект и this, только если вы хотите ссылаться на внутреннее закрытие:

var MyModule = (function ($) { 
    var self = {}; 

    var privateFunction = function() { 
     console.log(self); 
    } 

    self.init = function() { 
     privateFunction(); // exposes all the public methods of self, keeping the "private" functions private 
    }; 

    return self; 
}(jQuery)); 

MyModule.init(); 

https://jsfiddle.net/zz11n5wp/2/

+0

Спасибо. Я немного увеличил ваш пример, чтобы отслеживать 'self' и' this' при нескольких вызовах функций. Оба показывают действительное «это» в любом случае, а также доступ к другим частным предметам. Это говорит о том, что я делаю что-то не так, потому что ваш пример демонстрирует то, что я хочу, но не получаю. https://jsfiddle.net/BloodBaz/zz11n5wp/5/ –

+0

Если вы находитесь во внутренней области, вы сможете продолжить просмотр переменных во внешнем. Это означает, что вы можете получить доступ к частным функциям и переменным внутри вашей области действия, но вы не сможете получить доступ к ним извне. См. Пример: https://jsfiddle.net/zz11n5wp/6/ Я не уверен, что происходит в вашем коде :) – Jack

0

вы можете попробовать связывание функции с областью вы хотите? Вид, как показано ниже

var self = this;  
$.each([1,2,3,4], function(index, item) { 
    // do something 
    // self === this 
}.bind(this)); 

Или, если вам нужна старая поддержка браузера, попробуйте использовать библиотеку как lodash или что-то, чтобы сделать это. Или jquery's $.proxy должен работать.

https://jsfiddle.net/zz11n5wp/3/

+0

Спасибо @ vernak2539. Я думал, что 'bind()' может сыграть определенную роль в решении. Он действительно представляет желаемую «эту» анонимную функцию, которая великолепна.Однако, как только я вызываю 'initFruit()' (и косвенно 'initFruitSub()'), контекст снова переходит в глобальный контекст. Нормально ли ожидать, что нужно использовать '.call()' или '.bind()' для ВСЕХ вызовов функции-функции внутри модуля, чтобы поддерживать 'this' модуля? Благодарю. –

+0

Сфера - забавная вещь в JS. это действительно зависит от вашей ситуации и от вызова функций. В этом случае вам может потребоваться использовать call/apply для получения желаемых функций. или вы можете связать функции на верхнем уровне. Честно говоря, привязка все время действительно не стоит (иногда выглядит странно), просто чтобы использовать «это». Прибавление «это» на самом деле является хорошей идеей в некоторых случаях – vernak2539