6
var module = {};


(function(exports){

  exports.notGlobalFunction = function() {
    console.log('I am not global');
  };  

}(module));

function notGlobalFunction() {
  console.log('I am global');
}

notGlobalFunction(); //outputs "I am global"
module.notGlobalFunction(); //outputs "I am not global"

谁能帮我理解这里发生了什么?我知道如果你打电话notGlobalFunction(),它只会调用第二个函数。

但是在var module = {}做什么呢?为什么在第一个函数中再次调用它?

它说这通常被称为自执行匿名函数,但我真的不知道这意味着什么。

4

4 回答 4

25

立即调用的函数通常用于创建一个局部函数范围,该范围是私有的,不能从外部世界访问,并且可以定义它自己的局部符号而不影响外部世界。这通常是一种很好的做法,但在这种特殊情况下,我认为它除了增加几行代码之外没有任何好处,因为它没有用于任何事情。

这段代码:

(function(exports){

  exports.notGlobalFunction = function() {
    console.log('I am not global');
  };  

}(module));

将与没有像这样立即调用的一段代码相同:

module.notGlobalFunction = function() {
   console.log('I am not global');
};  

不同的是,首先,为modules被调用exports创建了一个别名,该别名对于立即调用的功能块是本地的。但是,别名并没有做任何独特的事情,代码也可以modules直接使用。


该变量modules被创建为单个全局父对象,然后可以将许多其他全局变量作为属性。这通常被称为“命名空间”。这通常是一个很好的设计模式,因为它最大限度地减少了可能与同一项目/页面中使用的其他代码冲突的顶级全局变量的数量。

因此,不要像这样制作多个顶级变量:

var x, y, z;

可以像这样制作一个顶级变量:

var modules = {};

然后,将所有其他全局变量作为属性附加到它:

modules.x = 5;
modules.y = 10;
modules.z = 0;

这样,虽然仍有多个全局变量,但只有一个可能与其他代码冲突的顶级全局变量。


类似地,立即调用的函数会创建一个本地私有作用域,其中可以创建该作用域的本地变量,并且不会干扰其他代码段:

(function() {
    var x, y, z;

    // variables x, y and z are available to any code inside this immediately invoked function
    // and they act like global variables inside this function block and
    // there values will persist for the lifetime of the program
    // But, they are not truly global and will not interfere with any other global
    // variables and cannot be accessed by code outside this block.
    // They create both privacy and isolation, yet work just as well


})();

将参数传递给立即调用的函数只是一种将值传递到立即调用的函数作用域的方法,该作用域将具有它自己的局部符号:

(function(exports) {
    // creates a local symbol in this function block called exports
    // that is assigned an initial value of module
})(module);
于 2013-01-14T16:48:55.967 回答
2

这将创建一个新的空对象:

var module = {};

它与以下内容相同:

var module = new Object();

这个包装:

(function(exports){
  ...
}(module));

module只为函数内部的变量添加别名。由于该匿名函数内没有局部变量或函数,因此您可以在没有它的情况下执行相同操作:

module.notGlobalFunction = function() {
  console.log('I am not global');
};  

例如,像这样的匿名函数可用于创建私有变量:

(function(exports){

  var s = 'I am not global';

  exports.notGlobalFunction = function() {
    console.log(s);
  };  

}(module));

现在notGlobalFunction添加到module对象的方法可以访问变量s,但没有其他代码可以访问它。

于 2013-01-14T16:48:36.607 回答
0

“自动执行”可能具有误导性。它是一个匿名函数表达式,它没有被分配或作为参数给出,而是被调用。在此处阅读有关立即调用函数表达式 (IIFE)的内容。

var module = {} 在做什么?

它初始化一个充当命名空间的空对象。

为什么在第一个函数中再次调用它?

它不是“调用”的,也不是“内部”第一个函数。该对象作为参数(“导出”)提供给 IEFE,并且在内部有一个分配给它的属性。

于 2013-01-14T16:51:06.707 回答
0

moduleIIFE 正在向作为参数传入的对象添加一个方法。该代码演示了函数创建范围。具有相同名称的方法被添加到对象和浏览器的头对象(窗口)中。

于 2013-01-14T16:52:55.517 回答