IIFE (Immediately-Invoked Function Expression) 立即执行函数表达式
请看下面的例子:
1 | var a = 2; |
1 | (function () {/* Code */}()); |
函数被包含在一对()
内部,成为了一个表达式,再通过在末尾加上另一个()
可以立即执行这个函数,比如:(function foo(){ .. })()
。第一个()
将函数变成表达式,第二个()
执行了这个函数。
这种函数表达式被社区成为:IIFE(Immediately Invoked Function Expresstion),立即执行函数表达式
IIFE的函数名不是必须的,IIFE最常见的用法是使用一个匿名函数表达式**。
1 | var a = 2; |
IIFE也可以用箭头函数:
1 | var a = 2; |
另一个改进的形式:(function(){ /* Code */ }())
仔细观察下面两个的区别:
1 | // IIFE 写法一 |
第一种形式中的函数表达式被包含在()
中,然后在后面用另一个()
括号来调用。
第二种形式中用来调用的()
括号被移进了用来包装的()
的括号中。
这两种形式在功能上是一致的
IIFE的另一种用法:把它们当作函数调用并传递参数进去
例如:
1 | var a = 2; |
解决undefined
标识符的默认值被错误覆盖导致的异常(并不常见)。
将一个参数名为undefined
,但是在对应的位置不传入任何值,这样就可以保证在代码中undefined
标识符的值真的是undefined
请看下面的例子:
1 | undefined = true; |
IIFE还有一种变化的用途是倒置代码的运行顺序,将需要运行的函数放在第二位,当作IIFE
执行之后的参数传递进去
请看下面的代码:
1 | var a = 2; |
这里将函数表达式def
定义在片段的第二部分,然后当作参数(这个参数也叫做def
)被传递进IIFE
函数定义的第一部分中,参数def
(也就是传递进去的函数)被调用,并将window
传入当作global
参数的值。
除了用()
还有很多方法可以达到同样的目的
1 | // IIFE |
为什么要使用IIFE
,它解决了什么问题?
不必为函数命名,避免了污染全局变量;(封装一些外部无法读取的私有变量)
IIFE
内部形成了一个单独的作用域;(隔离作用域,在ES6
之前JavaScript
只有函数作用域,没有块级作用域)
可以利用IIFE
写function
惰性载入
1 | // 写法一 |
上面代码中,写法二比写法一更好,因为完全避免了污染全局变量。
请看下面的例子:
1 | // 使用IIFE 获取时间,以年/月/日 时: 分: 秒的格式来赋给某个变量 |
参考链接
Medium What is an IIFE in JavaScript?
JavaScript Immediately-invoked Function Expressions (IIFE)
Mozilla Developer Network - IIFE
阮一峰-《JavaScript 标准参考教程(alpha)》
合理使用IIFE优化JS引擎的性能