但是我想理解为什么自执行函数的语法和它所具有的回调与所有其他JS语法都是如此不同..
(function () {
})()
我只需要理解为什么它有效地用()
封装它我不会猜到它是有效的,然后是额外的()
之后的回调,(它只是直接坐着在此之后,我也不会期望这是有效的。
有人能够向我解释这个吗?
答案 0 :(得分:14)
function (...) {...}
部分是函数表达式,即表示函数的表达式。在这种情况下,必须用括号括起来的唯一原因是,如果关键字function
是语句中的第一个东西,则该语句被假定为函数语句,也就是说,一个函数声明。 (实际上,它不一定要用括号括起来;它也可以用+
作为前缀,或者通常在function
之前放置任何类型的令牌来阻止函数声明的解释。)
函数表达式后的()
部分与调用函数的普通()
部分相同。这样:
(function (...) {...})(...);
(除临时变量外)与此相同:
var f = function (...) {...};
f();
相当于:
function f(...) {...};
f();
答案 1 :(得分:2)
基本上,外括号允许完全解释和实例化函数对象,这样一旦你退出这些括号的范围,就可以调用函数对象了。
答案 2 :(得分:2)
见这里:
当您声明时,您将其用作函数表达式(从上面的链接定义函数的第三种方式)。与任何表达式一样,此(expression)
计算表达式 - 此处使用的括号是必要时建立优先级。所以你可以这样写:
var f = function(a) {
var s = (((( 1 )))) + (((( a ))));
console.log(s);
};
((((( f ))))) (2);
(live example)然后删除具有相同结果的所有不必要的括号(基本上是1 + 2 = 3
的打印)。结果:
(function(...) { ... })
是一个接受一些参数并具有要执行的主体的函数。这样:
(function(...) { ... })()
几乎相当于:
var f = (function(...) { ... });
// Now f is a function that can be called
f();
除了其他原因之外,匿名函数很有用 - 有两个原因 - 它们是匿名的(即它们不会创建其他名称 - 再次参见上面的SOq链接)并且它们是其他不需要的东西的“容器”是全球性的。
答案 3 :(得分:0)
这里有一个立即调用的函数表达式,也称为IFFE(读取iffy),是一个使用JS函数作用域生成词法作用域的设计模式。这些用于避免变量提升,污染全局环境并同时允许公共访问方法,同时保留在函数中声明的变量的本地隐私。 理解这一点的关键是JS具有函数作用域而不是块作用域,并通过引用在闭包内传递值。 您可以在Immediately-invoked function expression。
进一步阅读此内容