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

时间:2014-11-07 17:05:20

标签: javascript design-patterns module-pattern

我正致力于实现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函数吗?

2 个答案:

答案 0 :(得分:1)

这就是弹出闭包的位置。privateHelloprivateLoggerprivateVar1privateVar2的范围限定在您立即调用的函数中,当您的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函数吗?

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

相关问题