日韩无码专区无码一级三级片|91人人爱网站中日韩无码电影|厨房大战丰满熟妇|AV高清无码在线免费观看|另类AV日韩少妇熟女|中文日本大黄一级黄色片|色情在线视频免费|亚洲成人特黄a片|黄片wwwav色图欧美|欧亚乱色一区二区三区

RELATEED CONSULTING
相關(guān)咨詢
選擇下列產(chǎn)品馬上在線溝通
服務(wù)時(shí)間:8:30-17:00
你可能遇到了下面的問題
關(guān)閉右側(cè)工具欄

新聞中心

這里有您想知道的互聯(lián)網(wǎng)營(yíng)銷解決方案
深入理解立即執(zhí)行函數(shù)

本文轉(zhuǎn)載自微信公眾號(hào)「神奇的程序員k」,作者神奇的程序員k。轉(zhuǎn)載本文請(qǐng)聯(lián)系神奇的程序員k公眾號(hào)。神奇的程序員K  

專業(yè)從事企業(yè)網(wǎng)站建設(shè)和網(wǎng)站設(shè)計(jì)服務(wù),包括網(wǎng)站建設(shè)、域名注冊(cè)、虛擬空間、企業(yè)郵箱、微信公眾號(hào)開發(fā)、微信支付寶重慶小程序開發(fā)、重慶APP開發(fā)公司、軟件開發(fā)、等服務(wù)。公司始終通過(guò)不懈的努力和以更高的目標(biāo)來(lái)要求自己,在不斷完善自身管理模式和提高技術(shù)研發(fā)能力的同時(shí),大力倡導(dǎo)推行新經(jīng)濟(jì)品牌戰(zhàn)略,促進(jìn)互聯(lián)網(wǎng)事業(yè)的發(fā)展。

 前言

立即執(zhí)行函數(shù)常用于第三方庫(kù),它可以用來(lái)隔離變量作用域,很多第三方庫(kù)都會(huì)存在大量的變量和函數(shù),在ES5環(huán)境下為了避免變量污染,開發(fā)者想到的解決辦法就是使用立即執(zhí)行函數(shù)。

本文就跟大家分享下立即執(zhí)行函數(shù)的相關(guān)知識(shí)點(diǎn),歡迎各位感興趣的開發(fā)者閱讀本文。

概念介紹

立即調(diào)用的匿名函數(shù)又被稱作立即調(diào)用的函數(shù)表達(dá)式(IIFE),它類似于函數(shù)聲明,但由于被包含在括號(hào)中,所以會(huì)被解釋為函數(shù)表達(dá)式。緊跟在第一組括號(hào)后面的第二組括號(hào)會(huì)立即調(diào)用前面的函數(shù)表達(dá)式,位于IIFE中的代碼在其外部是無(wú)法訪問的。

我們舉個(gè)例子來(lái)說(shuō)明下:

 
 
 
  1. (function() { 
  2.   // 塊級(jí)作用域 
  3.   for (var i = 0; i < 5; i++) { 
  4.     console.log(i); 
  5.   } 
  6. })(); 
  7. console.log(i); 

上述代碼中當(dāng)解析到console.log(i);時(shí),會(huì)報(bào)錯(cuò)ReferenceError: i is not defined,這是因?yàn)樗L問的變量是在IIFE內(nèi)部定義的,在外部訪問不到。

在es5以前,為了防止變量定義外泄,IIFE是個(gè)非常有效的方式,這樣也不會(huì)導(dǎo)致閉包相關(guān)的內(nèi)存問題,因?yàn)椴淮嬖趯?duì)這個(gè)匿名函數(shù)的引用。因此,只要函數(shù)執(zhí)行完畢,其作用域鏈就可以被銷毀。

IIFE的全稱為Immediately Invoked Function Expression,翻譯過(guò)來(lái)就是立即調(diào)用函數(shù)表達(dá)式。

模擬塊級(jí)作用域

使用IIFE可以模擬塊級(jí)作用域,即在一個(gè)函數(shù)表達(dá)式內(nèi)部聲明變量,然后立即調(diào)用這個(gè)函數(shù),這樣位于函數(shù)體作用域的變量就像是在塊級(jí)作用域中一樣(如上述例子所示)。

在ES6以后,新增了塊級(jí)作用域的概念,因此我們想實(shí)現(xiàn)同樣的效果,就無(wú)需再使用IIFE了,我們用let來(lái)重寫下上面的例子,代碼如下所示:

 
 
 
  1. for (let i = 0; i < 5; i++) { 
  2.   console.log(i); 
  3. console.log(i); 

有關(guān)變量作用域的更多知識(shí)點(diǎn)請(qǐng)移步我的另一篇文章:深入理解作用域和閉包

塊級(jí)作用域無(wú)法替代立即調(diào)用函數(shù)的表達(dá)式,當(dāng)你的代碼在不支持ES6+的瀏覽器上運(yùn)行時(shí),你不得不求助立即執(zhí)行函數(shù)來(lái)模擬。

實(shí)現(xiàn)私有變量

IIFE可以返回一個(gè)函數(shù)引用,當(dāng)這個(gè)函數(shù)在IIFE的詞法范圍外執(zhí)行,也會(huì)創(chuàng)建一個(gè)閉包,使函數(shù)能夠訪問局部變量。

我們舉個(gè)例子來(lái)說(shuō)明下,如下所示:

 
 
 
  1. const getOrderId = (function() { 
  2.   let count = 0; 
  3.   return function() { 
  4.     ++count; 
  5.     return `id_${count}`; 
  6.   }; 
  7. })(); 
  8. console.log(getOrderId()); 
  9. console.log(getOrderId()); 
  10. console.log(getOrderId()); 
  11. console.log(getOrderId()); 

上述代碼中:

  • 創(chuàng)建了一個(gè)自執(zhí)行函數(shù),其返回一個(gè)函數(shù)引用
  • 自執(zhí)行函數(shù)內(nèi)部有一個(gè)變量count,它就是一個(gè)私有變量,外部無(wú)法訪問
  • 最后,返回一個(gè)函數(shù)引用,形成閉包結(jié)構(gòu),對(duì)count自增后與_id進(jìn)行拼接并返回

在IIFE之外無(wú)法訪問函數(shù)內(nèi)部的count變量,除了從IIFE中返回的函數(shù),別處無(wú)法讀寫該變量,這樣就能創(chuàng)建真正的私有狀態(tài)變量。

變量重命名

在平常開發(fā)中可能遇到兩個(gè)不同的庫(kù),他們暴露的全局變量名卻是相同的,例如:正在使用Jquery,另一個(gè)庫(kù)也指定了一個(gè)名為$的全局變量。

為了解決命名沖突問題,可以將一段代碼封裝在一個(gè)IIFE中,將一個(gè)全局變量(比如Jquery)作為參數(shù)傳入IIFE,在函數(shù)內(nèi)部,就可以以一個(gè)任意的參數(shù)名(比如 $)來(lái)訪問該參數(shù)值,我們舉個(gè)例子來(lái)說(shuō)明下,如下所示:

 
 
 
  1. window.$ = function somethingElse() { 
  2.  
  3.     // 其他代碼 
  4.  
  5. }; 
  6.  
  7.   
  8.  
  9. (function($) { 
  10.  
  11.     // 其他代碼 
  12.  
  13. })(jQuery); 

不管在全局作用域有什么值指定給,在IIFE中,這些值都會(huì)被屏蔽,`參數(shù)一直指向Jquery方法。

捕獲全局對(duì)象

JavaScript代碼在不同環(huán)境執(zhí)行時(shí),所使用的全局對(duì)象是不同的,當(dāng)代碼在瀏覽器環(huán)境運(yùn)行時(shí),全局對(duì)象是window,但是在node環(huán)境下,全局對(duì)象則是global。

在寫通用js代碼時(shí),就可以利用IIFE將其包裝起來(lái),例如:

 
 
 
  1. (function(global) { 
  2.  
  3.     // 其他代碼 
  4.  
  5. })(this); 

包裝之后,在IIFE內(nèi)部使用global時(shí)在瀏覽器環(huán)境下其值就是window,node環(huán)境下其值就是global。

IIFE的兩種寫法

立即執(zhí)行函數(shù)有兩種寫法:

  • (function(){})() 匿名函數(shù)包裹在一個(gè)括號(hào)運(yùn)算符中,后面再跟一個(gè)小括號(hào)
  • (function(){}()) 匿名函數(shù)后面跟一個(gè)小括號(hào),然后整個(gè)包裹在一個(gè)括號(hào)運(yùn)算符中

上述兩種寫法是等價(jià)的,要想立即執(zhí)行函數(shù)做到立即執(zhí)行,要注意兩點(diǎn):

  • 函數(shù)體后面要有小括號(hào)
  • 函數(shù)體必須是函數(shù)表達(dá)式而不能是函數(shù)聲明

函數(shù)的聲明方式

在講它們兩者之間的區(qū)別之前,我們先來(lái)了解下js函數(shù)的兩種聲明方式:表達(dá)式和聲明式。

函數(shù)的聲明式寫法為:function test(){},這種寫法會(huì)導(dǎo)致函數(shù)提升,所有通過(guò)function關(guān)鍵字聲明的變量都會(huì)被解釋器優(yōu)先編譯,不管聲明在什么位置都可以調(diào)用它,但是它本身并不會(huì)被執(zhí)行。

 
 
 
  1. test(); // 測(cè)試 
  2. function test() { 
  3.   console.log("測(cè)試"); 
  4. test(); // 測(cè)試 

函數(shù)的表達(dá)式寫法為:var test = function(){},這種寫法不會(huì)導(dǎo)致函數(shù)提升,必須先聲明后調(diào)用,不然就會(huì)報(bào)錯(cuò)。

 
 
 
  1. test(); // 報(bào)錯(cuò):TypeError: test is not a function 
  2. var test = function() { 
  3.   console.log("測(cè)試"); 
  4. }; 

二者的區(qū)別

現(xiàn)在,我們回到正題,函數(shù)表達(dá)式加上()可以被直接調(diào)用,但是把整個(gè)聲明式函數(shù)用()包起來(lái)的話,則會(huì)被編譯器認(rèn)為是函數(shù)表達(dá)式,從而可以用()來(lái)直接調(diào)用,如(function test(){})()。

如果將括號(hào)加在聲明式函數(shù)后面如function test(){},運(yùn)行之后會(huì)報(bào)錯(cuò),因?yàn)椴环蟡s的語(yǔ)法,想讓其通過(guò)瀏覽器的語(yǔ)法檢查,就必須添加符號(hào),比如:()、+、!等,如下所示:

 
 
 
  1. function test(){ 
  2.   console.log("測(cè)試"); 
  3. }(); // 報(bào)錯(cuò) SyntaxError: Unexpected token ')' 
  4.  
  5. +function test() { 
  6.   console.log("測(cè)試"); 
  7. }(); // 正常執(zhí)行 
  8.  
  9. -function test() { 
  10.   console.log("測(cè)試"); 
  11. }(); // 正常執(zhí)行 
  12.  
  13. !function test() { 
  14.   console.log("測(cè)試"); 
  15. }();  // 正常執(zhí)行 
  16.  
  17. ~function test() { 
  18.   console.log("測(cè)試"); 
  19. }();  // 正常執(zhí)行 
  20.  
  21. void function test() { 
  22.   console.log("測(cè)試"); 
  23. }();  // 正常執(zhí)行 
  24.  
  25. new function test() { 
  26.   console.log("測(cè)試"); 
  27. }();  // 正常執(zhí)行 

立即執(zhí)行函數(shù)一般也寫成匿名函數(shù),使用function關(guān)鍵字聲明一個(gè)函數(shù),但未給函數(shù)命名,通過(guò)這種方式聲明的函數(shù)就是匿名函數(shù),例如function(){}。

匿名函數(shù)不能單獨(dú)使用,否則會(huì)js語(yǔ)法報(bào)錯(cuò),需要用()包起來(lái),當(dāng)我們需要給匿名函數(shù)傳值時(shí),寫在其后面的括號(hào)即可,例如:

 
 
 
  1. (function(val) { 
  2.   console.log(val); 
  3. }("我是匿名函數(shù)的參數(shù)")); 

講解到此處時(shí),我們會(huì)發(fā)現(xiàn),上述代碼的寫法正好是立即執(zhí)行函數(shù)的第二種寫法??,我們知道函數(shù)體后面跟著小括號(hào),這個(gè)函數(shù)就會(huì)立即執(zhí)行。

我們知道自執(zhí)行函數(shù)是需要用()將其包裹起來(lái)的,前面我們講到用()包裹起來(lái)的代碼,編譯器會(huì)認(rèn)定它為函數(shù)表達(dá)式,因此可以在其后面加個(gè)()立即調(diào)用這個(gè)函數(shù)。同時(shí)也可以從這個(gè)括號(hào)來(lái)為匿名函數(shù)傳參,代碼如下所示:

 
 
 
  1. (function(val) { 
  2.   console.log(val); 
  3. })("我是自執(zhí)行匿名函數(shù)"); 

我們發(fā)現(xiàn)上述代碼的寫法正好是立即執(zhí)行函數(shù)的第一種寫法??

寫在最后

至此,文章就分享完畢了。


分享題目:深入理解立即執(zhí)行函數(shù)
分享路徑:http://m.5511xx.com/article/cocijhe.html