高级JavaScript:为什么这个函数包含在括号中?

ner*_*ess 115 javascript syntax function parentheses iife

可能重复:
JavaScript中的(function(){})()构造是什么?

我遇到了一些JavaScript代码,但我不知道该怎么做.为什么运行此代码时会得到"1"?这个奇怪的小附录是什么(1),为什么函数包含在括号中?

(function(x){
    delete x;
    return x;
})(1);
Run Code Online (Sandbox Code Playgroud)

How*_*ard 238

这里有一些事情发生.首先是立即调用的函数表达式(IIFE)模式:

(function() {
  // Some code
})();
Run Code Online (Sandbox Code Playgroud)

这提供了一种在自己的范围内执行某些JavaScript代码的方法.通常使用它,以便在函数内创建的任何变量都不会影响全局范围.您可以使用此代替:

function foo() {
  // Some code
}
foo();
Run Code Online (Sandbox Code Playgroud)

但这需要给函数命名,这并不总是必要的.使用命名函数也意味着在将来的某个时刻可以再次调用该函数,这可能是不可取的.通过以这种方式使用匿名函数,您可以确保它只执行一次.

此语法无效:

function() {
  // Some code
}();
Run Code Online (Sandbox Code Playgroud)

因为您必须将函数包装在括号中以使其作为表达式进行解析.更多信息请访问:http://benalman.com/news/2010/11/immediately-invoked-function-expression/

那么快速回顾一下IIFE模式:

(function() {
  // Some code
})();
Run Code Online (Sandbox Code Playgroud)

允许"一些代码"立即执行,就好像它只是内联编写一样,但也在其自己的范围内,以免影响全局命名空间(因此可能会干扰或受到其他脚本的干扰).

您可以像传统函数一样将参数传递给函数,例如,

(function(x) {
  // Some code
})(1);
Run Code Online (Sandbox Code Playgroud)

所以我们传递值'1'作为函数的第一个参数,它接收它作为一个名为x的本地范围变量.

其次,你有功能代码本身的勇气:

delete x;
return x;
Run Code Online (Sandbox Code Playgroud)

删除操作符将从对象中删除属性.它不会删除变量.所以;

var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);
Run Code Online (Sandbox Code Playgroud)

记录的结果如下:

{'baz':5}
Run Code Online (Sandbox Code Playgroud)

然而,

var foo = 4;
delete foo;
console.log(foo);
Run Code Online (Sandbox Code Playgroud)

将记录值4,因为foo是一个变量而不是属性,因此无法删除它.

许多人认为删除可以删除变量,因为autoglobals的工作方式.如果分配给变量而不先声明它,它实际上不会变成变量,而是全局对象上的属性:

bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this!
delete bar;
console.log(bar); // Error - bar is not defined.
Run Code Online (Sandbox Code Playgroud)

这次删除有效,因为您不是删除变量,而是删除全局对象上的属性.实际上,前面的代码片段相当于:

window.bar = 4;
delete window.bar;
console.log(window.bar);
Run Code Online (Sandbox Code Playgroud)

现在您可以看到它与foo对象示例的类似,而不是foo变量示例.

  • 很好的解释。另外,作为旁注,我看到道格拉斯·克罗克福德(Douglas Crockford)在一次演讲中提到他更喜欢 (function() {}()); 为了清晰起见,将整个 IIFE 有效地包装在括号中 - 更具表现力。 (2认同)
  • @Utku是的,确切地说 (2认同)

xda*_*azz 11

这意味着您创建了一个匿名函数,并使用参数调用它1.

它与以下内容相同:

function foo(x) {
    delete x;
    return x;
}
foo(1);
Run Code Online (Sandbox Code Playgroud)

  • 我会使用`var foo = function(){}`避免混淆函数语句和函数表达式. (2认同)