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

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/9053842/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 08:30:58  来源:igfitidea点击:

Advanced JavaScript: Why is this function wrapped in parentheses?

javascriptfunctionsyntaxparenthesesiife

提问by nerdess

Possible Duplicate:
What is the (function() { } )() construct in JavaScript?

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

I came across this bit of JavaScript code, but I have no idea what to make out of it. Why do I get "1" when I run this code? What is this strange little appendix of (1) and why is the function wrapped in parentheses?

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

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

回答by Howard

There are a few things going on here. First is the immediately invoked function expression(IIFE) pattern:

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

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

This provides a way to execute some JavaScript code in its own scope. It's usually used so that any variables created within the function won't affect the global scope. You could use this instead:

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

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

But this requires giving a name to the function, which is not always necessary. Using a named function also means at some future point the function could be called again which might not be desirable. By using an anonymous function in this manner you ensure it's only executed once.

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

This syntax is invalid:

此语法无效:

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

Because you have to wrap the function in parentheses in order to make it parse as an expression. More information is here: http://benalman.com/news/2010/11/immediately-invoked-function-expression/

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

So to recap quickly on the IIFE pattern:

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

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

Allows 'some code' to be executed immediately, as if it was just written inline, but also within its own scope so as not to affect the global namespace (and thus potentially interfere with or be interfered with by, other scripts).

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

You can pass arguments to your function just as you would a normal function, for example,

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

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

So we're passing the value '1' as the first argument to the function, which receives it as a locally scoped variable, named x.

因此,我们将值 '1' 作为第一个参数传递给函数,该函数将其作为局部作用域变量接收,名为 x。

Secondly, you have the guts of the function code itself:

其次,你有函数代码本身的胆量:

delete x;
return x;

The delete operator will remove properties from objects. It doesn't delete variables. So;

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

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

Results in this being logged:

结果被记录:

{'baz':5}

Whereas,

然而,

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

will log the value 4, because foo is a variable not a property and so it can't be deleted.

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

Many people assume that delete can delete variables, because of the way autoglobals work. If you assign to a variable without declaring it first, it will not actually become a variable, but a property on the global object:

由于自动全局变量的工作方式,许多人认为 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.

This time the delete works, because you're not deleting a variable, but a property on the global object. In effect, the previous snippet is equivalent to this:

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

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

And now you can see how it's analogous to the foo object example and not the foo variable example.

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

回答by xdazz

It means you created an anonymous function, and call it with parameter 1.

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

It is just the same as:

它与以下内容相同:

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

回答by dmp

The reason that you still get 1 returned is that the delete keyword is for removing properties of objects. The rest is as others have commented, anything wrapped in brackets executes as a function, and the second set of brackets are the arguments passed to that block.

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

Here's the MDN reference for delete, and the MDN reference for closures, which discusses also anonymous functions.

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

回答by hugomg

People normally call these "Immediately Invoked Function Expressions" or "Self Executing Functions".

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

The point of doing this is that variables declared inside that function do not leak to the outside.

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