高级 JavaScript: 为什么这个函数用括号括起来?

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

我偶然发现了这段 JavaScript 代码,但我不知道该如何理解它。为什么我运行这个代码时得到“1”?(1)的这个奇怪的附录是什么? 为什么函数用括号括起来?

(function(x){
delete x;
return x;
})(1);
38329 次浏览

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

这就像:

function foo(x) {
delete x;
return x;
}
foo(1);

仍然得到1返回的原因是 关键字是用于删除对象的属性。其余部分与其他代码所注释的一样,括号中的任何内容都作为函数执行,第二组括号是传递给该块的参数。

下面是 用于删除的 MDN 引用用于闭包的 MDN 引用,它们也讨论匿名函数。

人们通常称之为“立即调用函数表达式”或“自执行函数”。

这样做的要点是,在该函数内部声明的变量不会泄漏到外部。

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

(function() {
// Some code
})();

这提供了一种在自己的作用域内执行一些 JavaScript 代码的方法。它通常用于使函数中创建的任何变量都不会影响全局作用域。你可以用这个代替:

function foo() {
// Some code
}
foo();

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

此语法无效:

function() {
// Some code
}();

因为必须用括号包装函数才能将其解析为表达式。更多信息请看: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

因此,让我们快速回顾一下 IIFE 模式:

(function() {
// Some code
})();

允许立即执行“某些代码”,就好像它只是内联编写的一样,但也要在它自己的范围内执行,以免影响全局名称空间(从而可能干扰或受到其他脚本的干扰)。

你可以像传递普通函数一样传递参数,

(function(x) {
// Some code
})(1);

所以我们将值’1’作为第一个参数传递给函数,函数将它作为一个局部作用域变量接收,该变量名为 x。

其次,你有函数代码本身的内核:

delete x;
return x;

删除操作符将从对象中删除属性

var foo = {'bar':4, 'baz':5};
delete foo.bar;
console.log(foo);

记录的结果是:

{'baz':5}

然而,

var foo = 4;
delete foo;
console.log(foo);

将记录值4,因为 foo 是一个变量而不是属性,所以它不能被删除。

许多人认为 delete 可以删除变量,因为自动全局变量是这样工作的。如果你赋值一个变量而没有先声明它,它实际上不会变成一个变量,而是全局对象上的一个属性:

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

这一次,delete 可以正常工作,因为您删除的不是变量,而是全局对象上的属性。实际上,前面的代码片段相当于:

window.bar = 4;
delete window.bar;
console.log(window.bar);

现在您可以看到它是如何类似于 foo 对象示例而不是 foo 变量示例的。