Javascript模块模式,私有变量去哪里?

Javascript模块模式,私有变量去哪里?,javascript,design-patterns,module-pattern,Javascript,Design Patterns,Module Pattern,我正在致力于实现Javascript模块模式,我非常了解如何很好地使用它。我不理解的是,一旦函数运行并指定了返回值,私有变量和方法会发生什么 如果我有这样一个模块: var myModule = (function() { var privateVar1, privateVar2 = 10, privateLogger, privateHello; privateLogger = function(someInput) { console.log(someInput); }; pri

我正在致力于实现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函数都会被重新定义?

这就是闭包弹出的地方。
privateHello
privateLogger
privateVar1
privateVar2
的作用域是立即调用的函数,当您的
publicIncrementor
函数正在访问这些私有变量(它们在
publicIncrementor
作用域之外)时,将创建一个闭包

所以,来回答你的问题:它现在生活在关闭状态。关于你的问题,如果每次都重新定义它,我不是100%确定,但据我所知,每次从局部范围之外访问变量时都会重新创建一个闭包,但它不会重新定义对象,而是始终引用相同的对象

有许多有趣的答案涉及闭包,因此您可能想看看以下答案:

在原始代码中(问题更新之前),变量声明列表中缺少
privateholl
,因此您的
privateholl
实际上是全局的

现在,您已经将
privatehollo
添加到
var
列表中(很好地指出),因此它目前只是模块构造函数范围内的一个局部变量

我现在试着回答你的问题

由此看来,myModule现在似乎是一个只知道什么是publicVar、publicCounter和publicIncrementor的变量。那么它怎么知道什么是privateHello呢

myModule
实例不直接“知道”
privateholl
,从某种意义上说,您可以通过某种方式“接触”到
privateholl
只有
myModule

但是用于创建
myModule
的构造函数在其主体的局部变量中声明
privatehollo

实例化后,该函数定义存在于何处

在记忆中的某个地方

它不是myModule的一部分(console.log(myModule)没有显示它)

是的。它只是没有分配给
myModule
的任何属性

它不是一个全局函数(避免这是此模式的要点)

现在不是,在你之前的问题中是这样的

那么函数定义现在在哪里

物理上,它在计算机内存中的某个地方。从逻辑上讲,它只是模块构造函数中的一个局部变量。
privateVar1
在哪里?他们可能是私人住宅的邻居你好

还是每次调用
myModule.publicIncrementor
时都会重新定义privateHello函数


如果不知道“重新定义”的语义,很难回答。它可能每次都是相同的函数“实例”,但我想这是一个实现细节。您是否担心获得本地定义函数的新示例?不要这样做。

是的,我确实编辑了问题以改变这一点。当我在节点中运行一些检查时,我记录了全局对象并看到了privateHello函数,但没有看到privateIncrementor,对此感到困惑。然而,后来我意识到这是因为缺少变量。我编辑它是因为我知道看到的原因,而这并不是我真正想问的问题。你能告诉我如何记录和检查myModule构造函数的文本吗?如果我能够做到这一点,我会在该@RV的输出中看到privatehollo吗?@RV只有
myModule
实例?我想你不能。如果我答对了您的问题,您会问“如何获取返回给定对象实例的函数?”。所以如果这是你问的,那么我想你不能。可能有一些技巧可以做到这一点,但我所知道或使用的都不是。谢谢,在某种程度上,我只需要一个术语来描述正在发生的事情。所以,让我知道研究闭包是一个很大的帮助。同样,在研究闭包的过程中,我忽略了这个练习中的生活部分,这是一个很大的疏忽,因为它是一个范围问题。这个链接非常有用: