中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

javascript立即執行函數表達式IIFE的示例分析

發布時間:2021-07-27 14:38:43 來源:億速云 閱讀:185 作者:小新 欄目:web開發

這篇文章主要為大家展示了“javascript立即執行函數表達式IIFE的示例分析”,內容簡而易懂,條理清晰,希望能夠幫助大家解決疑惑,下面讓小編帶領大家一起研究并學習一下“javascript立即執行函數表達式IIFE的示例分析”這篇文章吧。

一、IIFE解釋

全拼Imdiately Invoked Function Expression,立即執行的函數表達式。

像如下的代碼所示,就是一個匿名立即執行函數:

(function(window, undefined){
 // 代碼... 
})(window);

二、括號的意義

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

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

~function(){
 // 代碼...
}();

或者這種方式:

+function(){
 // 代碼...
}();

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

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

javascript立即執行函數表達式IIFE的示例分析

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命名空間綁定方法say
 WALL.say = function(){
  console.log('hello');
 };
})(window, wall);
(function(window, WALL, undefined){
 // 給wall命名空間綁定方法 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命名空間綁定方法say
 WALL.say = function(){
  console.log('hello');
 }
 return WALL; // 返回引用
})(window, wall);
var wall = (function(window, WALL, undefined){
 if(typeof WALL == 'undefined'){
  WALL = {};
 }
 // 給wall命名空間綁定方法 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命名空間綁定方法say
 WALL.say = function(){
  console.log('hello');
 }
})(window, window.wall || (window.wall = {}));
(function(window, WALL, undefined){
 // 給wall命名空間綁定方法 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命名空間綁定方法say
 WALL.say = function(){
  console.log('hello');
 }
})(window, window.wall || (window.wall = {}));

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

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

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

由于a.js文件的wall.log()少寫了分號,跟b.js文件合并后,js就會認為‘wall.log()(...)'是需要這么執行的,結果代碼就報錯了。

以上是“javascript立即執行函數表達式IIFE的示例分析”這篇文章的所有內容,感謝各位的閱讀!相信大家都有了一定的了解,希望分享的內容對大家有所幫助,如果還想學習更多知識,歡迎關注億速云行業資訊頻道!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

康定县| 新昌县| 梓潼县| 江安县| 建水县| 聊城市| 襄汾县| 左贡县| 福州市| 涞源县| 张家界市| 烟台市| 同仁县| 威海市| 酒泉市| 阿克陶县| 蒙山县| 泸西县| 长顺县| 鸡泽县| 孟连| 化德县| 依兰县| 九江市| 静安区| 历史| 亚东县| 神农架林区| 铜川市| 凉山| 闸北区| 子洲县| 澄迈县| 陆河县| 固镇县| 手机| 民县| 和静县| 安义县| 商洛市| 辽阳市|