詳解javascript立即執行函數運算式IIFE,javascriptiife

來源:互聯網
上載者:User

詳解javascript立即執行函數運算式IIFE,javascriptiife

一、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){ // 給wall命名空間Binder 方法say WALL.say = function(){  console.log('hello'); };})(window, wall);(function(window, WALL, undefined){ // 給wall命名空間Binder 方法 whoIam WALL.whoIam = function(){  console.log('wall'); };})(window, wall);// 調用wall.say();wall.whoIam();

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

不足的地方就是必須先聲明一個命名空間,然後才能執行相關的綁定代碼。存在順序載入的問題。

4.2 放大模式

var wall = (function(window, WALL, undefined){ if(typeof WALL == 'undefined'){  WALL = {}; } // 給wall命名空間Binder 方法say WALL.say = function(){  console.log('hello'); } return WALL; // 返回引用})(window, wall);var wall = (function(window, WALL, undefined){ if(typeof WALL == 'undefined'){  WALL = {}; } // 給wall命名空間Binder 方法 whoIam WALL.whoIam = function(){  console.log('wall'); } return WALL; // 返回引用})(window, wall);// 調用wall.say();wall.whoIam();

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

因為js允許wall變數進行重複var聲明,所以這段代碼是可以執行的。

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

需要注意的點:

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

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

4.3 寬放大模式

(function(window, WALL, undefined){ // 給wall命名空間Binder 方法say WALL.say = function(){  console.log('hello'); }})(window, window.wall || (window.wall = {}));(function(window, WALL, undefined){ // 給wall命名空間Binder 方法 whoIam WALL.whoIam = function(){  console.log('wall'); }})(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){ // 給wall命名空間Binder 方法say WALL.say = function(){  console.log('hello'); }})(window, window.wall || (window.wall = {}));

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

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

// a.js 檔案wall.log()// b.js 檔案(function(window, WALL, undefined){ // 給wall命名空間Binder 方法say WALL.say = function(){  console.log('hello'); }})(window, window.wall || (window.wall = {}));

由於a.js檔案的wall.log()少寫了分號,跟b.js檔案合并後,js就會認為‘wall.log()(...)'是需要這麼執行的,結果代碼就報錯了。

覺得不錯的,可以關注模組化這個系列的文章,容我後續碼字,敬請期待!

以上就是本文的全部內容,希望本文的內容對大家的學習或者工作能帶來一定的協助,同時也希望多多支援幫客之家!

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.