它是立即调用的函数表达式 ,简称IIFE 。它在创建后立即执行。
它与任何事件的任何事件处理程序无关(例如document.onload
)。
考虑第一对括号中的部分: ( <b>function(){}</b> )();
.... 这是一个正则函数表达式。然后查看最后一对(function(){}) <b>()</b> ;
,通常将其添加到表达式中以调用函数;在这种情况下,我们的先前表达。
当试图避免污染全局名称空间时,通常使用此模式,因为 IIFE 内部使用的所有变量(如在任何其他常规函数中一样)在其范围之外不可见。
这就是为什么您可能将此构造与window.onload
的事件处理程序混淆的原因,因为它经常被这样使用:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
该函数在创建后立即执行,而不是在解析之后执行。在执行脚本块中的任何代码之前,都将对其进行分析。同样,解析代码不会自动意味着它已被执行,例如,如果 IIFE 在函数内部,则直到调用该函数后,它才会被执行。
更新由于这是一个非常受欢迎的话题,值得一提的是,IIFE 也可以使用ES6 的 arrow 函数编写(就像Gajus 在评论中指出的那样):
((foo) => foo)('foo value')
它只是创建后立即执行的匿名函数。
就像您将其分配给变量,然后在没有变量的情况下立即使用它:
var f = function () {
};
f();
在 jQuery 中,您可能会想到类似的构造:
$(function(){
});
这是绑定ready
事件的简写形式:
$(document).ready(function(){
});
但是以上两个构造不是IIFE 。
立即调用的函数表达式(IIFE)立即调用一个函数。这仅表示该函数在定义完成后立即执行。
另外三种常用的措词:
// Crockford's preference - parens on the inside
(function() {
console.log('Welcome to the Internet. Please follow me.');
}());
//The OPs example, parentheses on the outside
(function() {
console.log('Welcome to the Internet. Please follow me.');
})();
//Using the exclamation mark operator
//https://stackoverflow.com/a/5654929/1175496
!function() {
console.log('Welcome to the Internet. Please follow me.');
}();
如果对其返回值没有特殊要求,那么我们可以这样写:
!function(){}(); // => true
~function(){}(); // => -1
+function(){}(); // => NaN
-function(){}(); // => NaN
或者,它可以是:
~(function(){})();
void function(){}();
true && function(){ /* code */ }();
15.0, function(){ /* code */ }();
您甚至可以写:
new function(){ /* code */ }
31.new function(){ /* code */ }() //If no parameters, the last () is not required