Javascript 什么是自执行匿名函数,或者这段代码在做什么?

Javascript 什么是自执行匿名函数,或者这段代码在做什么?,javascript,function,self-executing-function,Javascript,Function,Self Executing Function,有人能帮我理解这里发生了什么吗?我知道如果调用notGlobalFunction(),它只会调用第二个函数 但是var模块={}在做什么?为什么在第一个函数中再次调用它 它说这通常被称为自动执行匿名函数,但我真的不知道这是什么意思。这会创建一个新的空对象: var module = {}; (function(exports){ exports.notGlobalFunction = function() { console.log('I am not global');

有人能帮我理解这里发生了什么吗?我知道如果调用
notGlobalFunction()
,它只会调用第二个函数

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


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

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

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"
其作用与:

var module = {};
此包装器:

var module = new Object();
仅完成在函数内为变量
模块
添加别名。由于该匿名函数中没有局部变量或函数,因此您可以在没有它的情况下执行相同的操作:

(function(exports){
  ...
}(module));
例如,类似这样的匿名函数可用于创建私有变量:

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

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

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

这段代码:

(function(exports){

  var s = 'I am not global';

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

}(module));
与没有如下立即调用的代码相同:

(function(exports){

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

}(module));
module.notGlobalFunction = function() {
   console.log('I am not global');
};  
var x, y, z;
与之不同的是,在第一种情况下,创建了名为
导出的
模块的别名,该别名位于立即调用的功能块的本地。但是,别名没有任何独特之处,代码也可以直接使用
模块


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

因此,不要像这样创建多个顶级变量:

(function(exports){

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

}(module));
module.notGlobalFunction = function() {
   console.log('I am not global');
};  
var x, y, z;
可以创建一个顶级变量,如下所示:

(function(exports){

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

}(module));
module.notGlobalFunction = function() {
   console.log('I am not global');
};  
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


})();
“自动执行”可能具有误导性。它是一个匿名函数表达式,不是作为参数赋值或给定的,而是被调用的。请继续阅读这里

var module={}在做什么

它初始化用作命名空间的空对象

为什么在fist函数中再次调用它


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

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

您搜索过“自动执行匿名函数”吗?在web和stackoverflow上都有很好的效果。自动执行的匿名函数是一个自动执行的匿名函数!是的,但我仍然不确定第一个函数中发生了什么。从技术上讲,它不是自动执行的,因为它不调用自己。正如Bergi所指出的,
iLife
更为正确。感谢您的详细回答。我真的很感激!XD喜欢这个社区。很好的答案,对格式有很好的关注。但与其说是“自动执行”功能,不如说是“立即调用”;一个重要的区别。“自动执行”函数将从自身内部调用自身。这种匿名函数后面的括号只调用函数,实际上它们本身不在函数的作用域内(因此它会立即执行,但不会自动执行)。我做了一个编辑来反映这一点。@guypursey-我不明白为什么你认为短语
自动执行函数
会让任何人感到困惑,或者为什么
立即调用函数
是传达这个概念的更好方式“自动执行函数”是一个常用的短语,在我看来,它是描述正在发生的事情的一种清晰的方式(注意,在OP的问题标题中也使用了它),我不知道它如何与其他任何东西混淆。我没有还原您的编辑,但我不相信您的术语是更好的描述方式。@guypursey-注意,技术上正确的描述类似于立即调用匿名函数表达式的
,但是没有人想在正常写作中使用这个短语,所以我使用了一个速记描述性短语
自动执行函数
,它只是一个易于与概念关联的描述性速记。@jfriend00感谢您接受编辑,如果它看起来很迂腐,请道歉。这个词是在问题中使用的,所以我理解你为什么在回答中使用它。也许问题也应该反映这一点,或者答案可以包括这样一行:“提供的模式实际上不是一个自动执行的函数,而是一个立即调用的函数。”我认为这一区别很重要,因为可能有一个真正的自动执行函数,即一个调用自身的函数