最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

javascript中IIFE立即執(zhí)行函數(shù)表達(dá)式來龍去脈解析

 更新時間:2025年07月01日 08:59:46   作者:前端風(fēng)云志  
Ben?Alman于2010年提出IIFE立即執(zhí)行函數(shù)表達(dá)式,取代舊稱Self-ExecutingAnonymousFunction,通過括號包裹函數(shù)聲明轉(zhuǎn)為表達(dá)式,實現(xiàn)立即執(zhí)行,常見形式為()包裹,其他變種如new、void等不推薦使用,感興趣的朋友一起看看吧

介紹

IIFE(Immediately Invoked Function Expression),中文名稱:立即執(zhí)行函數(shù)表達(dá)式,其實IIFE最早并不叫這個名字,而是叫做Self-Executing Anonymous Function,即自執(zhí)行匿名函數(shù)。根據(jù)MDN的資料,IIFE這個說法最早由Ben Alman于2010年提出,下面我們一起來看看這個名字的來龍去脈。

2010年11月5日,Ben Alman寫下來他的著名文章:Immediately-Invoked Function Expression (IIFE),標(biāo)志著IIFE這個名字的誕生。

在文章中,Ben Alman稱他是一個對待術(shù)語非常嚴(yán)謹(jǐn)?shù)娜?,之前他多次看?code>Self-Executing Anonymous Function這個說法,覺得不是很恰當(dāng),于是他提出了Immediately-Invoked Function Expression這個說法。

IIFE到底是咋來的?

當(dāng)我們定義一個函數(shù)或者一個函數(shù)表達(dá)式時,你得到的是一個名字,通過這個名字,你就可以調(diào)用這個函數(shù)。

下面這兩段代碼,第一個定義了一個普通函數(shù),第二個定義了一個函數(shù)表達(dá)式,這兩種形式,我們都可以通過標(biāo)識符foo來調(diào)用它們。

// 普通函數(shù)
function foo() {
  console.log('I am a function');
}
// 函數(shù)表達(dá)式
const foo = function() {
  console.log('I am a function expression');
};

也就是說,當(dāng)javascript解釋器遇到全局function關(guān)鍵字,或者一個函數(shù)內(nèi)部的function關(guān)鍵字時,會將其解釋為一個函數(shù)聲明。

然而函數(shù)聲明是無法直接調(diào)用的,所以下面的寫法會導(dǎo)致錯誤:

function foo() {
  console.log('I am a function'); // Uncaught SyntaxError: Unexpected token ')'
}();

我們來分析一下,上面這段代碼,javascript解釋器會將其解釋為一個函數(shù)聲明,和一個分組操作符(()), 分組操作符是用來改變運算符優(yōu)先級的,里面必須有表達(dá)式才行,所以javascript解釋器會報錯。

那我們就給它一個表達(dá)式:

function foo() {
  console.log('I am a function'); // Uncaught SyntaxError: Unexpected token ')'
}(1);

這回代碼不報錯了,但是這段代碼毫無意義,這個函數(shù)并沒有執(zhí)行,實際上這段代碼與下面的代碼等價:

function foo() {
  console.log('I am a function');
}
(1);

它的返回值就是1,這不是我們想要的結(jié)果,我們需要函數(shù)定義后能立即被執(zhí)行,那就需要我們告訴javascript解釋器,這個函數(shù)是一個表達(dá)式,而不是一個聲明,因為表達(dá)式可以立即執(zhí)行,但是聲明不能。

而在javascript中,生成表達(dá)式最簡單的方式就是用()包裹起來,于是有了下面的代碼

(function foo() {
  console.log('I am a function');
});

這樣函數(shù)聲明就變成了一個函數(shù)表達(dá)式,但是這個表達(dá)式?jīng)]有名字,我們沒法調(diào)用它,我們先給它一個名字,然后通過名字調(diào)用它。

const bar = (function foo() {
  console.log('I am a function');
});
bar(); // I am a function

這樣完全沒有問題,但是這里的bar實在有點多余,實際上bar

(function foo() {
  console.log('I am a function');
});

是等價的,既然bar()可以調(diào)用函數(shù),那么我們直接在函數(shù)表達(dá)式末尾加上(),也可以調(diào)用這個函數(shù),于是就有了下面的代碼,這就是IIFE的由來。

(function foo() {
  console.log('I am a function');
})();

()寫在外層的括號內(nèi)也一樣,這種方式頗得javascript專家Douglas Crockford的青睞。我本人更喜歡第一種。

(function() {
  console.log('I am a function');
}());

IIFE的變種

由上面介紹可知,生成IIFE的精髓就是將函數(shù)聲明變成函數(shù)表達(dá)式,而在javascript中,生成表達(dá)式可不止使用()包裹起來這一種方式,還有很多其他的方式可以實現(xiàn)。于是IIFE也就是產(chǎn)生了諸多變種。

這個變種利用賦值運算符=來實現(xiàn),賦值運算符是將右側(cè)表達(dá)式的值賦值給左側(cè)變量的,所以它右側(cè)的部分被解析成了函數(shù)表達(dá)式及其調(diào)用。

const i = function() {
  console.log('I am an IIFE');
}();

下面的表中使用邏輯運算符來生成表達(dá)式。

true & (function() {
  console.log('I am an IIFE');
}());

還有下面這些,都是利用一元運算符來生成函數(shù)表達(dá)式。

!function(){ /* code */ }();
~function(){ /* code */ }();
-function(){ /* code */ }();
+function(){ /* code */ }();

最后來一個不為人知的,void運算符會對其右側(cè)的表達(dá)是求值然后返回undefined。(void expression - 先對expression求值,然后返回undefined)。

void function() {
  console.log('I am an IIFE');
}();

還有使用new運算符來生成IIFE,這種方式比較少見,因為它會創(chuàng)建一個新的對象。

new function() {
  console.log('I am an IIFE');
}();

這些方式都比較偏門了,不建議使用,只是用來幫助我們理解IIFE的。

為什么Self-Executing Anonymous Function這個名字不好?

Ben Alman認(rèn)為這個名字有兩個問題:

Self-Executing:這個名字暗示函數(shù)會調(diào)用自己,但是實際上函數(shù)是立即被執(zhí)行的,而不是調(diào)用它自身。
比如下面的幾段代碼都會調(diào)用自己,但是這并不是IIFE的語義。

// 遞歸調(diào)用自身
function foo() { foo(); 
// 使用arguments.callee調(diào)用自身
const foo = function() { arguments.callee(); };

Anonymous:這個名字暗示函數(shù)是匿名的,但實際上函數(shù)可以有名字,也可以沒有名字,比如下面的例子:

// 有名字的IIFE
(function foo() {
  console.log('I am an IIFE');
})();

參考

https://web.archive.org/web/20171201033208/http://benalman.com/news/2010/11/immediately-invoked-function-expression/#iife

大家有時間可以去拜讀Ben Alman的原文,大佬寫的東西就是不一樣,通俗易懂,是我輩楷模!

到此這篇關(guān)于javascript中IIFE(立即執(zhí)行函數(shù)表達(dá)式)到底是咋來的?的文章就介紹到這了,更多相關(guān)javascript中IIFE(立即執(zhí)行函數(shù)表達(dá)式)到底是咋來的?內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • JS面試必備之如何實現(xiàn)一個精確的倒計時

    JS面試必備之如何實現(xiàn)一個精確的倒計時

    又到了金三銀四的季節(jié)了,面試的各位同學(xué)要開始準(zhǔn)備起來了,今天主要分享一個在面試中經(jīng)常被提到的一個面試題:倒計時,希望對大家有所幫助
    2024-03-03
  • JavaScript 判斷瀏覽器是否支持SVG的代碼

    JavaScript 判斷瀏覽器是否支持SVG的代碼

    SVG(可縮放矢量圖形),接下來將介紹下如何判斷瀏覽器是否支持SVG,感興趣的朋友可以參考下哈,希望本代碼對你有所幫助
    2013-03-03
  • 原生js實現(xiàn)九宮格拖拽換位

    原生js實現(xiàn)九宮格拖拽換位

    這篇文章主要為大家詳細(xì)介紹了原生js實現(xiàn)九宮格拖拽換位,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-01-01
  • JS HTML5拖拽上傳圖片預(yù)覽

    JS HTML5拖拽上傳圖片預(yù)覽

    這篇文章主要為大家詳細(xì)介紹了JS HTML5拖拽上傳圖片預(yù)覽的相關(guān)資料,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2016-07-07
  • javascript數(shù)組排序匯總

    javascript數(shù)組排序匯總

    本文給大家匯總了一下javascript的數(shù)組排序算法,包括冒泡排序、快速排序、插入排序、希爾排序,希望對大家熟悉javascript數(shù)組排序能夠有所幫助。
    2015-07-07
  • javascript實現(xiàn)下雪效果【實例代碼】

    javascript實現(xiàn)下雪效果【實例代碼】

    下面小編就為大家?guī)硪黄猨avascript實現(xiàn)下雪效果【實例代碼】。小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考
    2016-05-05
  • js刪除對象/數(shù)組中null、undefined、空對象及空數(shù)組方法示例

    js刪除對象/數(shù)組中null、undefined、空對象及空數(shù)組方法示例

    這篇文章主要給大家介紹了關(guān)于js刪除對象/數(shù)組中null、undefined、空對象及空數(shù)組的相關(guān)資料,文中通過示例代碼介紹的非常詳細(xì),需要的朋友可以參考借鑒,下面隨著小編一起來看看吧
    2018-11-11
  • JavaScript中捕獲與冒泡詳解及實例

    JavaScript中捕獲與冒泡詳解及實例

    這篇文章主要介紹了JavaScript中捕獲與阻止捕獲、冒泡與阻止冒泡詳解及實例的相關(guān)資料,需要的朋友可以參考下
    2017-02-02
  • javascript模擬實現(xiàn)計算器

    javascript模擬實現(xiàn)計算器

    這篇文章主要為大家詳細(xì)介紹了javascript模擬實現(xiàn)計算器,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2021-04-04
  • 原生js實現(xiàn)無縫輪播圖

    原生js實現(xiàn)無縫輪播圖

    這篇文章主要為大家詳細(xì)介紹了原生js實現(xiàn)無縫輪播圖,文中示例代碼介紹的非常詳細(xì),具有一定的參考價值,感興趣的小伙伴們可以參考一下
    2020-01-01

最新評論

咸丰县| 博罗县| 岑巩县| 十堰市| 文安县| 江西省| 南昌市| 昌图县| 甘孜县| 曲阳县| 新营市| 色达县| 商南县| 高雄市| 武宣县| 聊城市| 察哈| 曲水县| 道孚县| 长武县| 滦南县| 阳谷县| 永德县| 武宣县| 深圳市| 忻城县| 西宁市| 奉新县| 新化县| 都昌县| 周宁县| 盐池县| 晋中市| 讷河市| 巧家县| 南靖县| 余庆县| 涡阳县| 孝义市| 正阳县| 如皋市|