在ES5環(huán)境下立即執(zhí)行函數(shù)的示例分析

在ES5環(huán)境下立即執(zhí)行函數(shù)的示例分析,針對這個問題,這篇文章詳細(xì)介紹了相對應(yīng)的分析和解答,希望可以幫助更多想解決這個問題的小伙伴找到更簡單易行的方法。

創(chuàng)新互聯(lián)公司-專業(yè)網(wǎng)站定制、快速模板網(wǎng)站建設(shè)、高性價比濟寧網(wǎng)站開發(fā)、企業(yè)建站全套包干低至880元,成熟完善的模板庫,直接使用。一站式濟寧網(wǎng)站制作公司更省心,省錢,快速模板網(wǎng)站建設(shè)找我們,業(yè)務(wù)覆蓋濟寧地區(qū)。費用合理售后完善,十余年實體公司更值得信賴。

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

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

概念介紹

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

我們舉個例子來說明下:

(function() {   // 塊級作用域   for (var i = 0; i < 5; i++) {     console.log(i);   } })(); console.log(i);

上述代碼中當(dāng)解析到console.log(i);時,會報錯ReferenceError: i is not  defined,這是因為它訪問的變量是在IIFE內(nèi)部定義的,在外部訪問不到。

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

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

模擬塊級作用域

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

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

for (let i = 0; i < 5; i++) {   console.log(i); } console.log(i);

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

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

實現(xiàn)私有變量

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

我們舉個例子來說明下,如下所示:

const getOrderId = (function() {   let count = 0;   return function() {     ++count;     return `id_${count}`;   }; })(); console.log(getOrderId()); console.log(getOrderId()); console.log(getOrderId()); console.log(getOrderId());

上述代碼中:

  • 創(chuàng)建了一個自執(zhí)行函數(shù),其返回一個函數(shù)引用

  • 自執(zhí)行函數(shù)內(nèi)部有一個變量count,它就是一個私有變量,外部無法訪問

  • 最后,返回一個函數(shù)引用,形成閉包結(jié)構(gòu),對count自增后與_id進行拼接并返回

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

變量重命名

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

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

window.$ = function somethingElse() {      // 其他代碼  };     (function($) {      // 其他代碼  })(jQuery);

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

捕獲全局對象

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

在寫通用js代碼時,就可以利用IIFE將其包裝起來,例如:

(function(global) {      // 其他代碼  })(this);

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

IIFE的兩種寫法

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

  • (function(){})() 匿名函數(shù)包裹在一個括號運算符中,后面再跟一個小括號

  • (function(){}()) 匿名函數(shù)后面跟一個小括號,然后整個包裹在一個括號運算符中

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

  • 函數(shù)體后面要有小括號

  • 函數(shù)體必須是函數(shù)表達式而不能是函數(shù)聲明

函數(shù)的聲明方式

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

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

test(); // 測試 function test() {   console.log("測試"); } test(); // 測試

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

test(); // 報錯:TypeError: test is not a function var test = function() {   console.log("測試"); };

二者的區(qū)別

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

如果將括號加在聲明式函數(shù)后面如function  test(){},運行之后會報錯,因為不符合js的語法,想讓其通過瀏覽器的語法檢查,就必須添加符號,比如:()、+、!等,如下所示:

function test(){   console.log("測試"); }(); // 報錯 SyntaxError: Unexpected token ')'  +function test() {   console.log("測試"); }(); // 正常執(zhí)行  -function test() {   console.log("測試"); }(); // 正常執(zhí)行  !function test() {   console.log("測試"); }();  // 正常執(zhí)行  ~function test() {   console.log("測試"); }();  // 正常執(zhí)行  void function test() {   console.log("測試"); }();  // 正常執(zhí)行  new function test() {   console.log("測試"); }();  // 正常執(zhí)行

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

匿名函數(shù)不能單獨使用,否則會js語法報錯,需要用()包起來,當(dāng)我們需要給匿名函數(shù)傳值時,寫在其后面的括號即可,例如:

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

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

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

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

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

關(guān)于在ES5環(huán)境下立即執(zhí)行函數(shù)的示例分析問題的解答就分享到這里了,希望以上內(nèi)容可以對大家有一定的幫助,如果你還有很多疑惑沒有解開,可以關(guān)注創(chuàng)新互聯(lián)行業(yè)資訊頻道了解更多相關(guān)知識。

當(dāng)前名稱:在ES5環(huán)境下立即執(zhí)行函數(shù)的示例分析
分享URL:http://bm7419.com/article16/gegodg.html

成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供響應(yīng)式網(wǎng)站、網(wǎng)站營銷品牌網(wǎng)站制作、全網(wǎng)營銷推廣Google、建站公司

廣告

聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶投稿、用戶轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請盡快告知,我們將會在第一時間刪除。文章觀點不代表本網(wǎng)站立場,如需處理請聯(lián)系客服。電話:028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時需注明來源: 創(chuàng)新互聯(lián)

網(wǎng)站建設(shè)網(wǎng)站維護公司