我正致力于实现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)没有显示它)。它不是一个全局函数(避免这种模式的重点)。那么这个函数定义现在在哪里?
或者每次调用myModule.publicIncrementor时都会重新定义privateHello函数吗?
答案 0 :(得分:1)
这就是弹出闭包的位置。privateHello
,privateLogger
,privateVar1
和privateVar2
的范围限定在您立即调用的函数中,当您的publicIncrementor
函数访问这些私有变量(在publicIncrementor
范围之外)时,会创建一个闭包。
所以,回答你的问题:它现在依旧关闭。关于你的问题,如果每次都重新定义,我不是100%肯定,但据我所知,每次从本地范围之外访问变量时都会重新创建一个闭包,但它没有&# 39;重新定义对象,而不是总是引用相同的对象。
有很多有趣的答案涵盖了闭包,所以你可能想看看以下答案: How do JavaScript closures work?
答案 1 :(得分:1)
在您的原始代码中(在问题更新之前),变量声明列表中缺少privateHello
,因此您的privateHello
实际上已变为全局。
现在您已将privateHello
添加到var
列表中(已发现),因此它当前只是模块构造函数范围内的局部变量。
我现在尝试回答你的问题。
从这一点来看,似乎myModule现在是一个只知道publicVar,publicCounter和publicIncrementor是什么的变量。那么它如何知道privateHello是什么?
myModule
实例没有"知道" privateHello
直接在某种意义上你可以以某种方式"伸出"至privateHello
只有myModule
。
但是用于创建myModule
的构造函数在其正文中的局部变量中声明privateHello
。
实例化后该函数定义存在于何处?
记忆中的某处。
它不是myModule的一部分(console.log(myModule)没有显示它。)
是的。它没有分配给myModule
的任何属性。
它不是一个全局函数(避免这就是这种模式的重点)。
现在不是,在您的问题的先前版本中它是。
那么这个函数定义现在在哪里?
从物理上讲,它位于计算机内存中的某个位置。逻辑上它只是模块构造函数中的局部变量。 privateVar1
住哪儿?他们可能是privateHello
的邻居。
或者每次拨打
myModule.publicIncrementor
时都会重新定义privateHello函数吗?
如果不知道"重新定义"的语义,很难回答。它可能是相同的"实例"每次的功能,但我想这是一个实现细节。您是否担心获得本地定义函数的新示例?唐'吨