我曾经知道这是什么意思,但我现在很挣扎......
这基本上是说document.onload
吗?
(function () {
})();
我曾经知道这是什么意思,但我现在很挣扎......
这基本上是说document.onload
吗?
(function () {
})();
它是一个立即调用的函数表达式,简称IIFE。它在创建后立即执行。
它与任何事件(例如document.onload
)的任何事件处理程序无关。
考虑第一对括号内的部分:....它是一个正则函数表达式。再看最后一对,这个一般是加在表达式中调用函数;在这种情况下,我们的先前表达式。(function(){})();
(function(){})();
当试图避免污染全局命名空间时,经常使用这种模式,因为在 IIFE 内部使用的所有变量(就像在任何其他普通函数中一样)在其范围之外是不可见的。
这就是为什么,也许,您将此构造与 for 的事件处理程序混淆window.onload
,因为它通常用作:
(function(){
// all your code here
var foo = function() {};
window.onload = foo;
// ...
})();
// foo is unreachable here (it’s undefined)
该函数在创建后立即执行,而不是在解析后执行。整个脚本块在其中的任何代码被执行之前被解析。此外,解析代码并不自动意味着它已被执行,例如,如果 IIFE 在一个函数内,那么在调用该函数之前它不会被执行。
更新 由于这是一个非常受欢迎的话题,值得一提的是 IIFE 也可以用ES6 的箭头函数编写(就像Gajus在评论中指出的那样):
((foo) => {
// do something with foo here 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
该构造称为立即调用函数表达式 (IIFE),这意味着它会立即执行。将其视为当解释器到达该函数时自动调用的函数。
最常见的用例:
它最常见的用例之一是限制通过var
. 通过创建的变量var
的范围仅限于一个函数,因此这个构造(它是围绕某些代码的函数包装器)将确保您的变量范围不会泄漏到该函数之外。
在下面的例子中,count
在立即调用的函数之外将不可用,即范围count
不会泄漏到函数之外。如果ReferenceError
您尝试在立即调用的函数之外访问它,您应该得到一个, 。
(function () {
var count = 10;
})();
console.log(count); // Reference Error: count is not defined
ES6 替代品(推荐)
在 ES6 中,我们现在可以通过let
和创建变量const
。它们都是块范围的(不同于var
函数范围的)。
因此,无需在我上面提到的用例中使用复杂的 IIFE 构造,您现在可以编写更简单的代码来确保变量的作用域不会泄漏到您想要的块之外。
{
let count = 10;
}
console.log(count); // ReferenceError: count is not defined
在这个例子中,我们用来let
定义count
变量,它count
限制了我们用大括号创建的代码块{...}
。
我称之为“curl监狱”。
也就是说立即执行。
所以如果我这样做:
var val = (function(){
var a = 0; // in the scope of this function
return function(x){
a += x;
return a;
};
})();
alert(val(10)); //10
alert(val(11)); //21
小提琴:http : //jsfiddle.net/maniator/LqvpQ/
var val = (function(){
return 13 + 5;
})();
alert(val); //18