js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( )) 有区别?
在SF上看到這樣一個(gè)問(wèn)題,我覺(jué)得問(wèn)得很好,所以弄成文章收集了。
沒(méi)有區(qū)別。
你需要明白 IIFE 的原理,我簡(jiǎn)單說(shuō)一下:
function foo() {...} // 這是定義,Declaration;定義只是讓解釋器知道其存在,但是不會(huì)運(yùn)行。foo(); // 這是語(yǔ)句,Statement;解釋器遇到語(yǔ)句是會(huì)運(yùn)行它的。IIFE 并非必須,傳統(tǒng)一點(diǎn)可以這么寫:
function foo() {...} foo();那么為什么要 IIFE?
傳統(tǒng)的方法啰嗦,定義和執(zhí)行分開寫;
傳統(tǒng)的方法直接污染全局命名空間(瀏覽器里的 global 對(duì)象,如 window)
于是,開發(fā)者們想找一個(gè)可以解決以上問(wèn)題的寫法。那么像下面這么寫行不行呢?
function foo(...){}();當(dāng)然是不能,但是為什么呢?因?yàn)?function foo(...){} 這個(gè)部分只是一個(gè)聲明,對(duì)于解釋器來(lái)說(shuō),就好像你寫了一個(gè)字符串 "function foo(...){}",它需要使用解析函數(shù),比如eval() 來(lái)執(zhí)行它才可以。所以把 () 直接放在聲明后面是不會(huì)執(zhí)行,這是錯(cuò)誤的語(yǔ)法。
如何把它變得正確?說(shuō)起來(lái)也簡(jiǎn)單,只要把 聲明 變成 表達(dá)式(Expression) 就可以了。
實(shí)際上轉(zhuǎn)變表達(dá)式的辦法還是很多的,最常見(jiàn)的辦法是把函數(shù)聲明用一對(duì) () 包裹起來(lái),于是就變成了:
(function foo() {...}) // 這里是故意換行,實(shí)際上可以和下面的括號(hào)連起來(lái) ();這就等價(jià)于:
var foo = function () {...}; // 這就不是定義,而是表達(dá)式了。 foo();但是之前我們說(shuō)不行的那個(gè)寫法,其實(shí)也可以直接用括號(hào)包起來(lái),這也是一種等價(jià)的表達(dá)式:
(function foo(){...}());所以答案是:木有區(qū)別~
另外,剛才說(shuō)過(guò)轉(zhuǎn)變表達(dá)式的方式很多,的確還有很多別的寫法,比如:
!function foo() {...}();或者
+function foo() {...}();這些都可以。
我個(gè)人挺偏愛(ài)用 void 來(lái)轉(zhuǎn)變表達(dá)式,因?yàn)榇岁P(guān)鍵字不會(huì)有返回值。不過(guò)這一點(diǎn)真的沒(méi)有什么要緊的,就當(dāng)我“龜毛”好了……
void function () {// 這里是真正需要的代碼 }();OK,所謂不去污染全局命名空間,是因?yàn)?IIFE 創(chuàng)建了一個(gè)新的函數(shù)作用域,你真正的業(yè)務(wù)代碼被封裝在其中,自然就不會(huì)觸碰到全局對(duì)象了。如果你需要全局對(duì)象,那就 pass 給 IIFE:
void function (global) {// 在這里,global 就是全局對(duì)象了 }(this) // 在瀏覽器里,this 就是 window 對(duì)象總結(jié)
以上是生活随笔為你收集整理的js立即执行函数: (function ( ){...})( ) 与 (function ( ){...}( )) 有区别?的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: 蓝忘机问灵十三载什么意思
- 下一篇: 【转】使用 vim + ctags +