立即執行函式表示式IIFE

2021-09-27 06:30:53 字數 3573 閱讀 5056

一、iife解釋

全拼imdiately invoked function expression,立即執行的函式表示式。
像如下的**所示,就是乙個匿名立即執行函式:

(function(window, undefined))(window);
二、括號的意義

2.1 包住function(){}的括號的意義

這個括號的目的,是為了把function(){}轉化為表示式。像一些庫的原始碼,喜歡用如下方式代替:

~function()();

或者這種方式:

+function()();

其實,作用都一樣,都是把function(){}轉化成乙個可執行的表示式,方便執行。

如果去掉該括號,則會報錯。因為單純的function(){}不是可執行的表示式,會直接報錯。如下圖:

2.1 第二個括號的意義

理解了第乙個括號的意義,第二個括號就很簡單了,就是執行表示式了。

三、引數的意義

以這段**為例子,講解引數

var wall = {};

(function(window, wall, undefined))(window, wall);

引數分為形參和實參。

function(window, wall, undefined)三個引數為形參,第二個括號(window, wall)的兩個引數為實參。

也即可以理解為 window == window,wall == wall。

2.1 普通形參

普通形參是指由window和wall這樣的實際變數傳入指定,可以為任何型別的變數。乙個形參就對應乙個實參

2.2 特殊形參undefined

為什麼形參要多寫乙個undefined,這是乙個很有趣的話題。

可以知道這個示例,實參只有兩個,而形參有三個。所以在函式執行的時候,形參undefined會預設賦值為undefined。

形參undefined的作用如下:

2.2.1 防止特殊值undefined被惡意**篡改。

ie6等低版本瀏覽器,undefined是支援被修改的。而這個特殊值被修改後,像以下這種判斷就失效了。

if(wall == undefined)
所以,這裡多加乙個形參的目的就是為了防止這種情況發生。只要在這個iife作用域內,undefined就能夠正常獲取到。

2.2.2 壓縮**可以壓縮undefined

因為undefined作為形參,像yui compressor這種型別的**壓縮工具,可以將其相關的值進行壓縮,減小檔案的體積。

四、寫法解析

4.1 普通寫法

var wall = {}; // 宣告定義乙個命名空間wall

// 定義方法

(function(window, wall, undefined);

})(window, wall);

(function(window, wall, undefined);

})(window, wall);

// 呼叫

wall.say();

wall.whoiam();

先定義乙個命名空間,然後再給這個命名空間加東西。這是最普遍的寫法,也是最好理解的。

不足的地方就是必須先宣告乙個命名空間,然後才能執行相關的繫結**。存在順序載入的問題。

4.2 放大模式

var wall = (function(window, wall, undefined);

}// 給wall命名空間繫結方法say

wall.say = function()

return wall; // 返回引用

})(window, wall);

var wall = (function(window, wall, undefined);

}// 給wall命名空間繫結方法 whoiam

wall.whoiam = function()

return wall; // 返回引用

})(window, wall);

// 呼叫

wall.say();

wall.whoiam();

放大模式的好處就是,可以不用考慮**載入的先後順序。

因為js允許wall變數進行重複var宣告,所以這段**是可以執行的。

我可以把iife函式拆分成多個檔案進行載入,而不會出現普通寫法需要注意的問題。

需要注意的點:

1.iife的頭部,都要先進行檢查命名空間是否已經例項化,如果還沒例項化,則進行例項化。

2.iife的尾部,都要return命名空間的引用,使後續**能夠得到最新的wall命名空間內容。

4.3 寬放大模式

(function(window, wall, undefined)

})(window, window.wall || (window.wall = {}));

(function(window, wall, undefined)

})(window, window.wall || (window.wall = {}));

// 呼叫

wall.say();

wall.whoiam();

寬放大模式的重點注意的地方:就是在實參部分的window.wall || (window.wall = {})。

用||運算子進行取巧。

如果window.wall是已經例項化的,非not defined。則直接返回window.wall的引用,賦值給形參wall。不會執行||運算子後面的內容。

如果window.wall還未例項化,則進行例項化。這裡要注意的點是例項化是乙個賦值操作,需要用括號包起來,變成表示式去執行,才不會報錯。

表示式(window.wall = {})執行完畢後,會返回新物件window.wall的引用。

寬放大模式的好處:是可以切割成多個檔案進行載入,而不必考慮檔案載入的先後順序,不存在強耦合關係。

當然,如果iife裡面的方法互相引用,還是存在載入依賴的問題。這個問題可以用載入器require.js等工具解決,這裡就不討論了。

五、分檔案載入iife要注意的點

;(function(window, wall, undefined)

})(window, window.wall || (window.wall = {}));

眼尖的已經看出區別了,就是檔案開始的地方,先寫上分號;。

這樣,多個檔案合併的時候,才不會出現收尾相接,**出現錯亂的問題。比如下面這種情況:

// a.js 檔案

wall.log()

// b.js 檔案

(function(window, wall, undefined)

})(window, window.wall || (window.wall = {}));

由於a.js檔案的wall.log()少寫了分號,跟b.js檔案合併後,js就會認為『wall.log()(…)』是需要這麼執行的,結果**就報錯了。

IIFE 立即執行函式表示式

原文 iife 的原理,我簡單說一下 function foo 這是定義,declaration 定義只是讓直譯器知道其存在,但是不會執行。foo 這是語句,statement 直譯器遇到語句是會執行它的。iife 並非必須,傳統一點可以這麼寫 function foo foo 那麼為什麼要 iif...

立即執行函式表示式 自執行函式

立即執行函式表示式,大部分人也稱為自執行函式。匿名函式 function 具名函式 function log 自執行函式的傳參 function add a,b 1,2 返回值let fn function add a,b 2,4 console.log fn 自執行函式也可以傳遞函式作為引數var...

javascript立即呼叫的函式表示式

1.什麼是自執行的匿名函式?它是指形如這樣的函式 function 2.疑問 為什麼 function 可以被執行,而function 卻會報錯?3.分析 1 首先,要清楚兩者的區別 function 是表示式,function 是函式宣告.2 其次,js 預編譯 的特點 js在 預編譯 階段,會解...