LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發文檔 其他文檔  
 
網站管理員

js中IIFE(立即執行函數表達式)到底是咋來的?

freeflydom
2025年7月3日 9:12 本文熱度 387

介紹

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

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

在文章中,Ben Alman稱他是一個對待術語非常嚴謹的人,之前他多次看到Self-Executing Anonymous Function這個說法,覺得不是很恰當,于是他提出了Immediately-Invoked Function Expression這個說法。

IIFE到底是咋來的?

當我們定義一個函數或者一個函數表達式時,你得到的是一個名字,通過這個名字,你就可以調用這個函數。

下面這兩段代碼,第一個定義了一個普通函數,第二個定義了一個函數表達式,這兩種形式,我們都可以通過標識符foo來調用它們。

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

也就是說,當javascript解釋器遇到全局function關鍵字,或者一個函數內部的function關鍵字時,會將其解釋為一個函數聲明。

然而函數聲明是無法直接調用的,所以下面的寫法會導致錯誤:

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

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

那我們就給它一個表達式:

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

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

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

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

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

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

這樣函數聲明就變成了一個函數表達式,但是這個表達式沒有名字,我們沒法調用它,我們先給它一個名字,然后通過名字調用它。

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()可以調用函數,那么我們直接在函數表達式末尾加上(),也可以調用這個函數,于是就有了下面的代碼,這就是IIFE的由來。

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

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

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

IIFE的變種

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

這個變種利用賦值運算符=來實現,賦值運算符是將右側表達式的值賦值給左側變量的,所以它右側的部分被解析成了函數表達式及其調用。

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

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

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

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

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

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

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

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

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

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

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

Ben Alman認為這個名字有兩個問題:

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

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

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

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

轉自https://www.cnblogs.com/graphics/p/18959048


該文章在 2025/7/3 9:12:40 編輯過
關鍵字查詢
相關文章
正在查詢...
點晴ERP是一款針對中小制造業的專業生產管理軟件系統,系統成熟度和易用性得到了國內大量中小企業的青睞。
點晴PMS碼頭管理系統主要針對港口碼頭集裝箱與散貨日常運作、調度、堆場、車隊、財務費用、相關報表等業務管理,結合碼頭的業務特點,圍繞調度、堆場作業而開發的。集技術的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業的高效ERP管理信息系統。
點晴WMS倉儲管理系統提供了貨物產品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質期管理,貨位管理,庫位管理,生產管理,WMS管理系統,標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務都免費,不限功能、不限時間、不限用戶的免費OA協同辦公管理系統。
Copyright 2010-2025 ClickSun All Rights Reserved

黄频国产免费高清视频,久久不卡精品中文字幕一区,激情五月天AV电影在线观看,欧美国产韩国日本一区二区
五月天在线视频婷婷播放 | 在线人成视频播放午夜福利网站 | 亚洲性夜夜综合久久9 | 色综合网天天综合色中文 | 伊人婷婷色香五月综合缴缴情 | 亚洲乱码中文字幕在线2021 |