在 Javascript 中,圆括号()
是一种运算符,跟在函数名之后,表示调用该函数。()
是函数的执行符号。比如,test()
就表示执行test函数。
我们需要在定义函数之后,立即执行该函数。这时,你不能在函数的定义之后加上圆括号,这会产生语法错误。
function(){ /* code */ }();
// SyntaxError: Unexpected token (
产生这个错误的原因是,function
这个关键字即可以当作声明语句,也可以当作表达式。
函数声明:function fnName(){ /* code */ }
函数表达式:var fnName = function() { /* code */ }
而只有表达式才能够被执行。
为了避免解析上的歧义,JavaScript 引擎规定,如果function
关键字出现在行首,一律解释成声明语句。因此,JavaScript引擎看到行首是function
关键字之后,认为这一段都是函数的定义,不应该以圆括号结尾,所以就报错了。
解决方法就是不要让function
出现在行首,让引擎将其理解成一个表达式。最简单的处理,就是将其放在一个圆括号里面。
官方写法:
(function (){}());
(W3C建议写法)
或(function (){})();
最后的分号
都是必须的。如果省略分号
,遇到连着两个 IIFE,可能就会报错。
推而广之,任何让解释器以表达式来处理函数定义的方法,都能产生同样的效果,比如下面写法。
var i = function(){ /* code */ }();
!function () { /* code */ }();
~function () { /* code */ }();
-function () { /* code */ }();
+function () { /* code */ }();
通常情况下,只对匿名函数使用这种立即执行的函数表达式,因为执行过后即释放该函数的引用,如下
function a(){ }
!function b(){ }();
console.log(a); //function a(){ }
console.log(b); //报错:b is not defined
立即执行的函数表达式目的有两个:
一 是不必为函数命名,避免了污染全局变量;
二 是 IIFE 内部形成了一个单独的作用域,可以封装一些外部无法读取的私有变量。