在许多书中/blog posts自调用匿名函数模式是这样写的:
(function() {
var foo = 'bar';
})();
但是运行 JSLint对此给出了这个错误:
Move the invocation into the parens that contain the function.
例如把它改成这个作品:
(function() {
var foo = 'bar';
}());
问题
- 为什么第一个实现对 JSLint 来说不够好?有什么区别?
- 首选的形式是什么? JSLint 总是正确的吗?
- 它为什么有效? 毕竟
function(){}()
抛出一个SyntaxError: Unexpected token (
但是用 parens 包裹它会突然起作用吗?例如 (function(){}()
) - 工作正常
(毕竟这是 JavaScript,而不是 Lisp,那么包装括号对 ohterwise 语法错误的影响是什么?)
编辑:这是对此的某种跟进(尽管我不会说完全重复):JSLint error: "Move the invocation into the parens that contain the function" ,所以我的主要问题是 #3,为什么它会起作用?
最佳答案
我不知道 Crockford 的观点是如何形成的,但我可以解释为什么用括号包裹有效。
JavaScript 中的函数 function() { ... }
语法可以表示两种不同的事物:函数声明或函数表达式。
函数声明是一个语句,它在指定名称下定义当前范围内的函数。
function example() {
alert("Hello World");
}
example();
函数表达式是一个表达式,其计算结果为新的Function
实例。
var secondExample = function example() {
alert("Hello World");
};
secondExample();
example(); // <-- throws an Error: example is not defined.
出现的语法是函数声明还是函数语句取决于解析器的预期。 JavaScript 的解析器很简单。它不会向前看并注意到函数后跟 ()
,因此它应该将其视为表达式。它只在一行的开头看到 function
,因此将其视为一个语句,当它后跟 ()
时会导致语法错误。当您将它括在括号中时,解析器会期待一个表达式,并且它可以工作。
用括号括起来(无论你把它们放在什么地方)是最清晰的方法,但是任何导致解析器期望表达式的东西都可以工作。例如,按位非运算符 ~
:
~function() {
alert("Hello World");
}();
关于javascript - 这些自执行匿名函数(又名 IIFE)实现之间有什么区别,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/16026909/