摘要:閉包與立即執(zhí)行函數(shù)前言最近在細(xì)讀高級(jí)程序設(shè)計(jì),對(duì)于我而言,中文版,書中很多地方翻譯的差強(qiáng)人意,所以用自己所理解的,嘗試解讀下。作用域鏈的這種配置機(jī)制引出了一個(gè)值得注意的副作用,即閉包只能取得包含任何變量的最后一個(gè)值。
閉包與立即執(zhí)行函數(shù)
前言:最近在細(xì)讀Javascript高級(jí)程序設(shè)計(jì),對(duì)于我而言,中文版,書中很多地方翻譯的差強(qiáng)人意,所以用自己所理解的,嘗試解讀下。如有紕漏或錯(cuò)誤,會(huì)非常感謝您的指出。文中絕大部分內(nèi)容引用自《JavaScript高級(jí)程序設(shè)計(jì)第三版》。
作用域鏈的這種配置機(jī)制引出了一個(gè)值得注意的副作用,即閉包只能取得包含任何變量的最后一個(gè)值。
function createArray(){ var result = new Array(); for(var i = 0; i < 10; i++) { result[i] = function() { return i; } } return result; }
這個(gè)函數(shù)會(huì)返回一個(gè)函數(shù)數(shù)組。表面上看,似乎每個(gè)函數(shù)都應(yīng)該返回自己的索引值,即位置0的函數(shù)返回0,位置1的函數(shù)返回1, 以此類推。
但實(shí)際上,每個(gè)函數(shù)都返回10,因?yàn)槊總€(gè)函數(shù)的作用域中都保存著createArray的活動(dòng)對(duì)象,所以他們引用的都是同一個(gè)變量i。
當(dāng)createArray()函數(shù)返回后,變量i的值是10,此時(shí)每個(gè)函數(shù)都引用著同一個(gè)變量i,所以i的值是10。
// 代碼執(zhí)行過程 createArray(); /* createArray() { var result = new Array(); var i; // 0,1,2,3,4,5,6,7,8,9,10 for ( i = 0; i < 10 ; i ++) { result[i] = function() { return i; // 注意 函數(shù)的執(zhí)行時(shí)機(jī),你只有調(diào)用函數(shù)的時(shí)候,才會(huì)產(chǎn)生執(zhí)行環(huán)境,沿著作用域鏈,找到活動(dòng)對(duì)象 // 這里有個(gè)閉包,還記得閉包的概念嗎? 有權(quán)訪問到另外一個(gè)函數(shù)作用域的變量的函數(shù) } } /* result[0] = function(){ return i } result[1] = function(){ return i } result[2] = function(){ return i } .... */ return result; } result = [function(){return i}, function(){return i}....]; */ createArray()[1](); // 10
那么如何讓這個(gè)函數(shù)的行為符合我們的預(yù)期呢?
可以通過創(chuàng)建另一個(gè)匿名函數(shù)強(qiáng)制讓閉包的行為符合預(yù)期,這里也應(yīng)用了立即執(zhí)行函數(shù)。
//立即執(zhí)行函數(shù) //我們平時(shí)寫函數(shù)然后調(diào)用是這么寫的。 //聲明函數(shù),調(diào)用執(zhí)行。 function foo(){ console.log("hi"); } foo(); // "hi" //那么,我們可不可以聲明調(diào)用寫一塊呢? 這就是申明函數(shù)立刻執(zhí)行。 //好像不可以,控制臺(tái)報(bào)錯(cuò) function foo(){ console.log("hi"); }(); //Uncaught SyntaxError: Unexpected token ) //那么如果用括號(hào)包裹呢? (function foo(){ console.log("hi"); }()); // "hi", 可以了。 這就是立即執(zhí)行函數(shù)!
有了立即執(zhí)行函數(shù),就可以強(qiáng)制讓閉包的行為符合我們的預(yù)期了。
//改寫代碼 function createArray() { var result = new Array(); for( var i = 0; i < 10; i ++ ) { result[i] = (function(i) { return function(){ return i; } }(i)); } return result; } createArray()[0](); // 0 createArray()[1](); // 1 createArray()[2](); // 2 // 這里不只有一種方法,其他方法在此不表。
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/98782.html
摘要:匿名函數(shù)是不能單獨(dú)寫的,所以就提不上立即執(zhí)行了。六立即執(zhí)行函數(shù)在閉包中的應(yīng)用立即執(zhí)行函數(shù)能配合閉包保存狀態(tài)。來看下上節(jié)內(nèi)容中閉包的例子現(xiàn)在,我們來利用立即執(zhí)行函數(shù)來簡(jiǎn)化它第一個(gè)匿名函數(shù)執(zhí)行完畢后,返回了第二個(gè)匿名函數(shù)。 前面的閉包中,提到與閉包相似的立即執(zhí)行函數(shù),感覺兩者還是比較容易弄混吧,嚴(yán)格來說(因?yàn)橄透叱虒?duì)閉包的定義不同),立即執(zhí)行函數(shù)并不屬于閉包,它不滿足閉包的三個(gè)條件。...
摘要:,立即執(zhí)行函數(shù)就是定義后馬上就執(zhí)行的函數(shù),用來隔絕作用域使無法在外部被訪問,函數(shù)訪問了函數(shù)外面的變量,這兩者就形成了閉包與形成了閉包閉包 1,立即執(zhí)行函數(shù)就是定義后馬上就執(zhí)行的函數(shù),用來隔絕作用域使 _foo 無法在外部被訪問 2,函數(shù)訪問了函數(shù)外面的變量,這兩者就形成了閉包get() 與 _foo 形成了閉包 (function() { var _foo = 1 window...
摘要:閉包是什么這是一個(gè)在面試的過程中出現(xiàn)的概率為以上的問題,也是我們張口就來的問題。文章推薦我們面試中在被問到閉包這個(gè)問題是要注意的幾點(diǎn)閉包的延伸,讓面試變得 閉包是什么?這是一個(gè)在面試的過程中出現(xiàn)的概率為60%以上的問題,也是我們張口就來的問題。但是我們往往發(fā)現(xiàn),在面試的過程中我們的回答并不那么讓面試官滿意,我們雖然能張口說出一些但是卻不能系統(tǒng)的對(duì)這個(gè)問題進(jìn)行回答。面試官希望加入自己團(tuán)隊(duì)...
摘要:目錄執(zhí)行環(huán)境與作用域鏈立即執(zhí)行函數(shù)閉包知識(shí)點(diǎn)什么是閉包使用閉包的意義與注意點(diǎn)閉包的具體應(yīng)用小結(jié)這是基本語法的函數(shù)部分的第篇文章,主要講述了中比較重要的知識(shí)點(diǎn)閉包在講閉包之前,在上一篇函數(shù)二的基礎(chǔ)上,進(jìn)一步深化執(zhí)行環(huán)境和作用域鏈的知識(shí)點(diǎn),并補(bǔ) 目錄 1.執(zhí)行環(huán)境與作用域鏈 2. 立即執(zhí)行函數(shù) 3. 閉包知識(shí)點(diǎn) 3.1 什么是閉包 3.2 使用閉包的意義與注意點(diǎn) 3.3 閉包的具體應(yīng)用 4...
摘要:閉包面試題解由于作用域鏈機(jī)制的影響,閉包只能取得內(nèi)部函數(shù)的最后一個(gè)值,這引起的一個(gè)副作用就是如果內(nèi)部函數(shù)在一個(gè)循環(huán)中,那么變量的值始終為最后一個(gè)值。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第8天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了...
閱讀 1517·2021-11-18 10:02
閱讀 1657·2021-09-04 16:40
閱讀 3171·2021-09-01 10:48
閱讀 874·2019-08-30 15:55
閱讀 1853·2019-08-30 15:55
閱讀 1365·2019-08-30 13:05
閱讀 3013·2019-08-30 12:52
閱讀 1624·2019-08-30 11:24