在SF上看到如许一个题目,我以为问得很好,所以弄成文章收集了。
没有区分。
你须要邃晓 IIFE 的道理,我简朴说一下:
function foo() {...} // 这是定义,Declaration;定义只是让诠释器晓得其存在,然则不会运转。
foo(); // 这是语句,Statement;诠释器遇到语句是会运转它的。
IIFE 并不是必需,传统一点能够这么写:
function foo() {...}
foo();
那末为何要 IIFE?
传统的要领烦琐,定义和实行离开写;
传统的要领直接污染全局定名空间(浏览器里的 global 对象,如 window)
因而,开发者们想找一个能够处理以上题目的写法。那末像下面这么写行不可呢?
function foo(...){}();
当然是不能,然则为何呢?由于 function foo(...){}
这个部份只是一个声明,关于诠释器来讲,就好像你写了一个字符串 "function foo(...){}"
,它须要运用剖析函数,比方eval()
来实行它才能够。所以把 ()
直接放在声明背面是不会实行,这是毛病的语法。
怎样把它变得准确?说起来也简朴,只要把 声明 变成 表达式(Expression) 就能够了。
实际上改变表达式的方法照样许多的,最常见的方法是把函数声明用一对 () 包裹起来,因而就变成了:
(function foo() {...}) // 这里是有意换行,实际上能够和下面的括号连起来
();
这就等价于:
var foo = function () {...}; // 这就不是定义,而是表达式了。
foo();
然则之前我们说不可的谁人写法,实在也能够直接用括号包起来,这也是一种等价的表达式:
(function foo(){...}());
所以答案是:木有区分~
别的,适才说过改变表达式的体式格局许多,确实另有许多别的写法,比方:
!function foo() {...}();
或许
+function foo() {...}();
这些都能够。
我个人挺偏爱用 void 来改变表达式,由于此关键字不会有返回值。不过这一点真的没有什么要紧的,就当我“龟毛”好了……
void function () {
// 这里是真正须要的代码
}();
OK,所谓不去污染全局定名空间,是由于 IIFE 创建了一个新的函数作用域,你真正的营业代码被封装在个中,天然就不会触遇到全局对象了。假如你须要全局对象,那就 pass 给 IIFE:
void function (global) {
// 在这里,global 就是全局对象了
}(this) // 在浏览器里,this 就是 window 对象