2014-11-07 4 views
1

Я работаю над реализацией шаблона модуля Javascript, и я понимаю, как его использовать. То, что я не понимаю, - это концепция того, что происходит с частными переменными и методами после запуска функции и присвоением возвращаемого значения.Шаблон модуля Javascript, куда идут частные переменные?

Если у меня есть модуль, как так:

var myModule = (function() { 

var privateVar1, privateVar2 = 10, privateLogger, privateHello; 

privateLogger = function(someInput) { 
    console.log(someInput); 
}; 
privateHello = function() { console.log('Hello World!');} 

    return { 
    publicVar: 'myName', 
    publicCounter: 0, 
    publicIncrementor: function(bar) { 
     bar++; 
     privateLogger(bar); 
     privateHello(); 
    } 
    } 
})(); 
console.log(myModule); 
console.log(myModule.publicIncrementor.toString()); 

Когда я запускаю файл, я затем получить выход:

{ publicVar: 'myName', 
    publicCounter: 0, 
    publicIncrementor: [Function] } 
function (bar) { 
    bar++; 
    privateLogger(bar); 
    privateHello(); 
} 

Из этого, похоже, MyModule теперь переменная что знает только, что такое publicVar, publicCounter и publicIncrementor. Итак, как он узнает, что такое privateHello? Где это определение функции существует после создания экземпляра? Это не является частью myModule (console.log (myModule) не показывает его). Это не глобальная функция (исключая эту точку). Итак, где же теперь это определение функции?

Или это функция privateHello получает переопределение при каждом вызове myModule.publicIncrementor?

ответ

1

Это где закрытие поп в. privateHello, privateLogger, privateVar1 и privateVar2 находятся в области видимости для вашей немедленно вызываются функции, и когда ваша publicIncrementor функции доступ к этим приватному переменной (которые находятся вне publicIncrementor сферы), замыкание создано.

Итак, чтобы ответить на ваш вопрос: теперь он живет на закрытии. О вашем вопросе, если он будет переопределен каждый раз, я не уверен на 100%, но, насколько я знаю, закрытие воссоздается каждый раз, когда вы обращаетесь к переменной из-за пределов локальной области, но не переопределяет объекты, в вместо этого он всегда будет ссылаться на одни и те же объекты.

Есть много интересных ответов, которые охватывают замыкания, так что вы можете захотеть взглянуть на следующий ответ: How do JavaScript closures work?

+0

Спасибо, в некотором роде, что мне просто нужно было, чтобы описать, что происходит. Поэтому просто дать мне знать, чтобы закрыть исследования, это очень большая помощь. –

+0

Также, глядя на это, я игнорировал часть IIFE этого упражнения, что является большим недоверием, поскольку это вопрос сферы. –

+0

Эта ссылка была очень полезной: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Closures –

1

В исходном коде (до того, как вопрос был обновлен) privateHello было отсутствующим в список объявлений переменных, так что ваш privateHello фактически стал глобальным.

Теперь вы добавили privateHello в список var (хорошо пятнистый), поэтому в настоящее время это только локальная переменная в рамках функции вашего конструктора модулей.

Теперь я постараюсь ответить на ваши вопросы.

Из этого, похоже, myModule теперь является переменной, которая знает только, что publicVar, publicCounter и publicIncrementor. Итак, как он узнает, что такое privateHello?

myModule экземпляр «не знает» privateHello непосредственно в том смысле, что вы могли бы каким-то образом «достучаться» до privateHello только имея myModule.

Но функция-конструктор, используемая для создания myModule, объявляет privateHello в локальной переменной в ее теле.

Где это определение функции существует после создания экземпляра?

Где-то в памяти.

Это не часть myModule (console.log (myModule) не показывает его).

Это. Он просто не присваивается никакому свойству myModule.

Это не глобальная функция (исключая эту точку).

Теперь это не так, в предыдущей версии вашего вопроса было.

Итак, где же это определение функции сейчас?

Физически это где-то в памяти компьютера. Логически это всего лишь локальная переменная в функции конструктора модуля. Где живет privateVar1? Вероятно, они соседи с privateHello.

Или это функция privateHello получает переопределение при каждом вызове myModule.publicIncrementor?

Трудно ответить, не зная семантики «переопределенных». Вероятно, это будет один и тот же «экземпляр» функции каждый раз, но я думаю, что это деталь реализации. Вы беспокоитесь о получении новых образцов локально определенной функции? Не.

+0

Да, я редактировал вопрос, чтобы изменить это. Когда я запускал некоторые проверки в узле, я регистрировал глобальный объект и видел функцию privateHello, но не privateIncrementor, и был смущен. Однако тогда я понял, что это из-за недостающего var. Я отредактировал его, потому что я знал причину того, что я видел, и это был не вопрос, который я задавал. –

+0

Можете ли вы рассказать мне, как я могу регистрировать и проверять текст функции конструктора myModule? Если бы я смог это сделать, увидел бы ли я privateHello в результатах этого? –

+0

@RV Имея только экземпляр 'myModule'? Думаю, ты не можешь. Если я правильно задал вопрос, вы спрашиваете что-то вроде «Как я могу получить функцию, которая вернула данный экземпляр объекта?». Поэтому, если это то, о чем вы спрашиваете, я думаю, вы не можете. Вероятно, есть трюки, но я ничего не знаю и не знаю. – lexicore