我读了一些关于闭包的帖子,到处都看到了这个,但是没有明确的解释它是如何工作的——每次我都被告知要使用它…:
// Create a new anonymous function, to use as a wrapper
(function(){
// The variable that would, normally, be global
var msg = "Thanks for visiting!";
// Binding a new function to a global object
window.onunload = function(){
// Which uses the 'hidden' variable
alert( msg );
};
// Close off the anonymous function and execute it
})();
好的,我看到我们将创建一个新的匿名函数,然后执行它。所以在这之后,这段简单的代码应该工作了(它确实工作了):
(function (msg){alert(msg)})('SO');
我的问题是这里发生了什么魔法?当我写到:
(function (msg){alert(msg)})
然后将创建一个新的未命名函数,如function ""(msg)…
但为什么这行不通呢?
(function (msg){alert(msg)});
('SO');
为什么要在同一条线上?
你能给我指出一些帖子或者给我一个解释吗?
它不起作用的简单原因不是因为;表示匿名函数结束。这是因为在函数调用的末尾没有(),它就不是函数调用。也就是说,
function help() {return true;}
如果调用result = help();这是对函数的调用,返回true。
如果你拨打result = help;这不是电话。在这种分配中,帮助被视为要分配给结果的数据。
你所做的是通过添加分号来声明/实例化一个匿名函数,
(function (msg) { /* Code here */ });
然后尝试在另一个语句中调用它,只使用括号…显然,因为函数没有名称,但这将不起作用:
('SO');
解释器将第二行上的括号视为一个新的指令/语句,因此它不起作用,即使你这样做:
(function (msg){/*code here*/});('SO');
它仍然不能工作,但当您删除分号时,它可以工作,因为解释器会忽略空白和空格,并将完整的代码视为一条语句。
(function (msg){/*code here*/}) // This space is ignored by the interpreter
('SO');
Conclusion: a function call is not a function call without the () on the end unless under specific conditions such as being invoked by another function, that is, onload='help' would execute the help function even though the parentheses were not included. I believe setTimeout and setInterval also allow this type of function call too, and I also believe that the interpreter adds the parentheses behind the scenes anyhow which brings us back to "a function call is not a function call without the parentheses".
这个答案与问题没有严格的联系,但是您可能有兴趣发现这种语法特性并不是函数特有的。例如,我们总是可以这样做:
alert(
{foo: "I am foo", bar: "I am bar"}.foo
); // alerts "I am foo"
与函数相关。因为它们是继承自Function的对象。原型,我们可以这样做:
Function.prototype.foo = function () {
return function () {
alert("foo");
};
};
var bar = (function () {}).foo();
bar(); // alerts foo
你知道,我们甚至不需要用圆括号来包围函数来执行它们。不管怎样,只要我们试着把结果赋值给一个变量。
var x = function () {} (); // this function is executed but does nothing
function () {} (); // syntax error
对于函数,一旦声明了它们,就可以对它们调用new操作符并获得一个对象。以下是等价的:
var obj = new function () {
this.foo = "bar";
};
var obj = {
foo : "bar"
};
综上所述:
function() {
alert("hello");
}();
当未赋值给变量时,将产生语法错误。代码被解析为函数语句(或定义),这使得闭括号在语法上不正确。在函数部分周围添加圆括号告诉解释器(和程序员)这是一个函数表达式(或调用),如
(function() {
alert("hello");
})();
这是一个自调用函数,这意味着它是匿名创建的并立即运行,因为调用发生在声明它的同一行中。这个自调用函数使用熟悉的语法指示为调用无参数函数,在函数名周围加上括号:(myFunction)();。
有一个很好的SO JavaScript函数语法讨论。