js立即執(zhí)行函數(shù): (function ( ){})( ) 與 (function ( ){}( )) 有什么區(qū)別?
沒有區(qū)別。
你需要明白 IIFE 的原理,我簡單說一下:
function foo() {...} // 這是定義,Declaration;定義只是讓解釋器知道其存在,但是不會運(yùn)行。
foo(); // 這是語句,Statement;解釋器遇到語句是會運(yùn)行它的。
IIFE 并非必須,傳統(tǒng)一點(diǎn)可以這么寫:
function foo() {...}
foo();
那么為什么要 IIFE?
1.傳統(tǒng)的方法啰嗦,定義和執(zhí)行分開寫;
2.傳統(tǒng)的方法直接污染全局命名空間(瀏覽器里的 global 對象,如 window)
于是,開發(fā)者們想找一個可以解決以上問題的寫法。那么像下面這么寫行不行呢?
function foo(...){}();
當(dāng)然是不能,但是為什么呢?因?yàn)?function foo(...){} 這個部分只是一個聲明,對于解釋器來說,就好像你寫了一個字符串 "function foo(...){}",它需要使用解析函數(shù),比如 eval() 來執(zhí)行它才可以。所以把 () 直接放在聲明后面是不會執(zhí)行,這是錯誤的語法。
如何把它變得正確?說起來也簡單,只要把 聲明 變成 表達(dá)式(Expression) 就可以了。
實(shí)際上轉(zhuǎn)變表達(dá)式的辦法還是很多的,最常見的辦法是把函數(shù)聲明用一對 () 包裹起來,于是就變成了:
(function foo() {...}) // 這里是故意換行,實(shí)際上可以和下面的括號連起來
();
這就等價(jià)于:
var foo = function () {...}; // 這就不是定義,而是表達(dá)式了。
foo();
但是之前我們說不行的那個寫法,其實(shí)也可以直接用括號包起來,這也是一種等價(jià)的表達(dá)式:
(function foo(){...}());
所以你問有沒有區(qū)別?很簡單:木有~
另外,剛才說過轉(zhuǎn)變表達(dá)式的方式很多,的確還有很多別的寫法,比如:
!function foo() {...}();
或者
+function foo() {...}();
這些都可以。
我個人挺偏愛用 void 來轉(zhuǎn)變表達(dá)式,因?yàn)榇岁P(guān)鍵字不會有返回值。不過這一點(diǎn)真的沒有什么要緊的,就當(dāng)我“龜毛”好了……
void function () {
// 這里是真正需要的代碼
}();
OK,所謂不去污染全局命名空間,是因?yàn)?IIFE 創(chuàng)建了一個新的函數(shù)作用域,你真正的業(yè)務(wù)代碼被封裝在其中,自然就不會觸碰到全局對象了。如果你需要全局對象,那就 pass 給 IIFE:
void function (global) {
// 在這里,global 就是全局對象了
}(this) // 在瀏覽器里,this 就是 window 對象
我在這里寫過一個系列,其中一篇講作用域和命名提升的,里面的知識點(diǎn)對理解 IIFE 有幫助,有興趣的話可以繼續(xù)深入閱讀:http://chabaoo.cn/article/75090.htm
方式一,調(diào)用函數(shù),得到返回值。強(qiáng)制函數(shù)直接量執(zhí)行再返回一個引用,引用在去調(diào)用執(zhí)行
方式二,調(diào)用函數(shù),得到返回值。強(qiáng)制運(yùn)算符使函數(shù)調(diào)用執(zhí)行
(function(){})(); 是 把函數(shù)當(dāng)作表達(dá)式解析,然后執(zhí)行解析后的函數(shù)
相當(dāng)于 var a = function(){}; a(); a得到的是函數(shù)
(function(){}()); 是把函數(shù)表達(dá)式和執(zhí)行當(dāng)作語句直接執(zhí)行、
相當(dāng)于 var a = function(){}(); a得到的是結(jié)果
最終結(jié)果是一樣的、
()只是起了 自執(zhí)行的作用
和 () 一樣的還有很多
比如 +function (){}
這個等于 (function (){}) 一般用(function (){}) 還有個作用,就是 避免全局變量
- 深入理解javascript中的立即執(zhí)行函數(shù)(function(){…})()
- js 在定義的時候立即執(zhí)行的函數(shù)表達(dá)式(function)寫法
- JavaScript中立即執(zhí)行函數(shù)實(shí)例詳解
- 深入解析JavaScript中的立即執(zhí)行函數(shù)
- JavaScript立即執(zhí)行函數(shù)的三種不同寫法
- js中匿名函數(shù)的N種寫法
- JavaScript 匿名函數(shù)(anonymous function)與閉包(closure)
- js中匿名函數(shù)的創(chuàng)建與調(diào)用方法分析
- 淺析Javascript匿名函數(shù)與自執(zhí)行函數(shù)
- 詳談JavaScript 匿名函數(shù)及閉包
- Javascript自執(zhí)行匿名函數(shù)(function() { })()的原理淺析
- JS立即執(zhí)行的匿名函數(shù)用法分析
相關(guān)文章
詳解webpack與SPA實(shí)踐之開發(fā)環(huán)境搭建
這篇文章主要介紹了詳解webpack與SPA實(shí)踐之開發(fā)環(huán)境搭建,小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-12-12判斷javascript的數(shù)據(jù)類型(示例代碼)
這篇文章主要是對判斷javascript的數(shù)據(jù)類型(示例代碼)進(jìn)行了詳細(xì)的介紹,需要的朋友可以過來參考下,希望對大家有所幫助2013-12-12js動態(tài)調(diào)用css屬性的小規(guī)律及實(shí)例說明
本篇文章主要介紹了js動態(tài)調(diào)用css屬性的小規(guī)律及實(shí)例說明。需要的朋友可以過來參考下,希望對大家有所幫助2013-12-12js使用棧來實(shí)現(xiàn)10進(jìn)制轉(zhuǎn)8進(jìn)制與取除數(shù)及余數(shù)
這篇文章主要介紹了js使用棧來實(shí)現(xiàn)10進(jìn)制轉(zhuǎn)8進(jìn)制、js取除數(shù)、余數(shù),需要的朋友可以參考下2014-06-06工作中常用的js、jquery自定義擴(kuò)展函數(shù)代碼片段匯總
本文主要對工作中常用的js、jquery自定義擴(kuò)展函數(shù)代碼片段進(jìn)行了分享,具有很好的參考價(jià)值,需要的朋友一起來看下吧2016-12-12