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

IT技术 javascript function syntax parentheses iife
2021-01-27 11:23:10

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

我遇到了这段 JavaScript 代码,但我不知道该怎么做。为什么运行此代码时会得到“1”?(1) 这个奇怪的小附录是什么,为什么函数用括号括起来?

(function(x){
    delete x;
    return x;
})(1);
4个回答

这里发生了一些事情。首先是立即调用函数表达式(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;

delete 运算符将从对象中删除属性。它不会删除变量。所以;

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.

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

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

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

很好的解释。另外,作为旁注,我看到道格拉斯·克罗克福德(Douglas Crockford)在一次演讲中提到他更喜欢 (function() {}()); 为了清晰起见,将整个 IIFE 有效地包装在括号中 - 更具表现力。
2021-03-22 11:23:10
与维基链接相比,括号包裹了整个内容,这有什么区别吗?
2021-04-02 11:23:10
@Utku 是的,正是
2021-04-02 11:23:10
所以 in (function(x){ delete x; return x; })(1);delete x没有任何影响吧?因为x是变量,而不是属性。因此delete x没有任何效果对吗?
2021-04-03 11:23:10

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

它与以下内容相同:

function foo(x) {
    delete x;
    return x;
}
foo(1);
@missingno 他们是一样的。
2021-03-16 11:23:10
我会使用var foo = function(){}避免混淆函数语句和函数表达式。
2021-03-19 11:23:10

您仍然返回 1 的原因是delete 关键字用于删除对象的属性其余的就像其他人评论的那样,括号中的任何内容都作为函数执行,第二组括号是传递给该块的参数。

这是deleteMDN 参考,以及closuresMDN 参考,其中也讨论了匿名函数。

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

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