Advanced JavaScript: Why is this function wrapped in parentheses?
Possible Duplicate:
What is the (function() { } )() construct in JavaScript?
我遇到了这段javascript代码,但我不知道该怎么做。为什么运行此代码时得到"1"?(1)的这个奇怪的小附录是什么?为什么用括号括起来的函数?
1 2 3 4 | (function(x){ delete x; return x; })(1); |
这里发生了一些事情。首先是立即调用的函数表达式(IIFE)模式:
1 2 3 | (function() { // Some code })(); |
这提供了一种在自己的范围内执行一些JavaScript代码的方法。它通常用于在函数中创建的任何变量都不会影响全局范围。你可以用这个来代替:
1 2 3 4 | function foo() { // Some code } foo(); |
但这需要为函数命名,这并不总是必要的。使用一个命名的函数也意味着在将来的某个时候,可以再次调用这个函数,这可能是不可取的。通过以这种方式使用匿名函数,可以确保只执行一次。
此语法无效:
1 2 3 | function() { // Some code }(); |
因为您必须将函数括在括号中,以便将其作为表达式进行解析。更多信息请访问:http://benalman.com/news/2010/11/immediate-invoked-function-expression/
因此,要快速回顾一下生命周期模式:
1 2 3 | (function() { // Some code })(); |
允许立即执行"some code",就好像它刚被内联写入,但也在它自己的范围内,这样就不会影响全局命名空间(因此可能会干扰或被其他脚本干扰)。
例如,可以像传递普通函数一样将参数传递给函数,
1 2 3 | (function(x) { // Some code })(1); |
因此,我们将值"1"作为第一个参数传递给函数,该函数将其作为局部作用域变量(名为x)接收。
其次,您有函数代码本身的勇气:
1 2 | delete x; return x; |
删除操作符将从对象中删除属性。它不会删除变量。所以;
1 2 3 | var foo = {'bar':4, 'baz':5}; delete foo.bar; console.log(foo); |
记录结果:
1 | {'baz':5} |
然而,
1 2 3 | var foo = 4; delete foo; console.log(foo); |
将记录值4,因为foo是变量而不是属性,因此无法删除。
许多人认为删除可以删除变量,这是因为autoglobals的工作方式。如果在不首先声明变量的情况下为其赋值,则它实际上不会成为变量,而是全局对象上的属性:
1 2 3 | bar = 4; // Note the lack of 'var'. Bad practice! Don't ever do this! delete bar; console.log(bar); // Error - bar is not defined. |
这次删除有效,因为您没有删除变量,而是删除全局对象的属性。实际上,前面的代码片段相当于:
1 2 3 | window.bar = 4; delete window.bar; console.log(window.bar); |
现在您可以看到它是如何类似于foo对象示例而不是foo变量示例的。
这意味着您创建了一个匿名函数,并使用参数
它与以下内容相同:
1 2 3 4 5 | function foo(x) { delete x; return x; } foo(1); |
人们通常称之为"立即调用的函数表达式"或"自执行函数"。
这样做的目的是函数内部声明的变量不会泄漏到外部。
返回1的原因是delete关键字用于删除对象的属性。其余的正如其他人所评论的,括号中的任何内容都作为函数执行,第二组括号是传递给该块的参数。
这里是用于删除的MDN引用,以及用于闭包的MDN引用,其中还讨论了匿名函数。