国产xxxx99真实实拍_久久不雅视频_高清韩国a级特黄毛片_嗯老师别我我受不了了小说

資訊專欄INFORMATION COLUMN

javascript系列--javascript深入淺出圖解作用域鏈和閉包

Jensen / 3357人閱讀

摘要:變量對象也是有父作用域的。作用域鏈的頂端是全局對象。當(dāng)函數(shù)被調(diào)用的時(shí)候,作用域鏈就會(huì)包含多個(gè)作用域?qū)ο蟆.?dāng)函數(shù)要訪問時(shí),沒有找到,于是沿著作用域鏈向上查找,在的作用域找到了對應(yīng)的標(biāo)示符,就會(huì)修改的值。

一、概要

對于閉包的定義(紅寶書P178):閉包就是指有權(quán)訪問另外一個(gè)函數(shù)的作用域中的變量的函數(shù)。

關(guān)鍵點(diǎn):

1、閉包是一個(gè)函數(shù)

2、能夠訪問另外一個(gè)函數(shù)作用域中的變量

二、閉包特性

對于閉包有下面三個(gè)特性:

1、閉包可以訪問當(dāng)前函數(shù)以外的變量

function getOuter(){
var date = "815";
function getDate(str){

console.log(str + date);  //訪問外部的date

}
return getDate("今天是:"); //"今天是:815"
}
getOuter();

2、即使外部函數(shù)已經(jīng)返回,閉包仍能訪問外部函數(shù)定義的變量

function getOuter(){
var date = "815";
function getDate(str){

console.log(str + date);  //訪問外部的date

}
return getDate; //外部函數(shù)返回
}
var today = getOuter();
today("今天是:"); //"今天是:815"
today("明天不是:"); //"明天不是:815"

3、閉包可以更新外部變量的值

function updateCount(){
var count = 0;
function getCount(val){

count = val;
console.log(count);

}
return getCount; //外部函數(shù)返回
}
var count = updateCount();
count(815); //815
count(816); //816

三、作用域鏈

javascript中有一個(gè)執(zhí)行上下文(execution context)的概念,它定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù),決定它們各自的行為。每一個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對象,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對象中。你可以把它當(dāng)做Javascript的一個(gè)普通對象,但是你只能修改它的屬性,卻不能引用它。

變量對象也是有父作用域的。

作用域鏈定義:當(dāng)訪問一個(gè)變量時(shí),解釋器會(huì)首先在當(dāng)前作用域查找標(biāo)示符,如果沒有找到,就去父作用域找,直到找到該變量的標(biāo)示符或者不再存在父作用域了,這就是作用域鏈。

作用域鏈和原型繼承有點(diǎn)類似,但又有點(diǎn)小區(qū)別:如果去查找一個(gè)普通對象的屬性時(shí),在當(dāng)前對象和其原型中都找不到時(shí),會(huì)返回undefined;但查找的屬性在作用域鏈中不存在的話就會(huì)拋出ReferenceError。

作用域鏈的頂端是全局對象。對于全局環(huán)境中的代碼,作用域鏈只包含一個(gè)元素:全局對象。所以,在全局環(huán)境中定義變量的時(shí)候,它們就會(huì)被定義到全局對象中。當(dāng)函數(shù)被調(diào)用的時(shí)候,作用域鏈就會(huì)包含多個(gè)作用域?qū)ο蟆?/p> 四、全局環(huán)境

關(guān)于作用域鏈講得略多(紅皮書上有關(guān)于作用域及執(zhí)行環(huán)境的詳細(xì)解釋),看一個(gè)簡單地例子:

// my_script.js
"use strict";
var foo = 1;
var bar = 2;
在全局環(huán)境中,創(chuàng)建了兩個(gè)簡單地變量。如前面所說,此時(shí)變量對象是全局對象:

執(zhí)行上述代碼,my_script.js本身會(huì)形成一個(gè)執(zhí)行環(huán)境,以及它所引用的變量對象。

4.1無嵌套函數(shù)

// my_script.js
"use strict";

var foo = 1;
var bar = 2;

function myFunc() {

var a = 1;
var b = 2;
var foo = 3;
console.log("inside myFunc");

}

console.log("outside");
myFunc();
定義時(shí):當(dāng)myFunc被定義的時(shí)候,myFunc的標(biāo)識(shí)符(identifier)就被加到了全局對象中,這個(gè)標(biāo)識(shí)符所引用的是一個(gè)函數(shù)對象(myFunc function object)。

內(nèi)部屬性[[scope]]指向當(dāng)前的作用域?qū)ο螅簿褪呛瘮?shù)的標(biāo)識(shí)符被創(chuàng)建的時(shí)候,我們所能夠直接訪問的那個(gè)作用域?qū)ο螅慈謱ο螅?/p>

myFunc所引用的函數(shù)對象,其本身不僅僅含有函數(shù)的代碼,并且還含有指向其被創(chuàng)建的時(shí)候的作用域?qū)ο蟆?/p>

調(diào)用時(shí):當(dāng)myFunc函數(shù)被調(diào)用的時(shí)候,一個(gè)新的作用域?qū)ο蟊粍?chuàng)建了。新的作用域?qū)ο笾邪琺yFunc函數(shù)所定義的本地變量,以及其參數(shù)(arguments)。這個(gè)新的作用域?qū)ο蟮母缸饔糜驅(qū)ο缶褪窃谶\(yùn)行myFunc時(shí)能直接訪問的那個(gè)作用域?qū)ο螅慈謱ο螅?/p>

4.2嵌套函數(shù)

當(dāng)函數(shù)返回沒有被引用的時(shí)候,就會(huì)被垃圾回收器回收。但是對于閉包,即使外部函數(shù)返回了,函數(shù)對象仍會(huì)引用它被創(chuàng)建時(shí)的作用域?qū)ο蟆?/p>

"use strict";
function createCounter(initial) {
var counter = initial;

function increment(value) {

counter += value;

}

function get() {

return counter;

}

return {

increment: increment,
get: get

};
}

var myCounter = createCounter(100);
console.log(myCounter.get()); // 返回 100

myCounter.increment(5);
console.log(myCounter.get()); // 返回 105
當(dāng)調(diào)用 createCounter(100) 時(shí),內(nèi)嵌函數(shù)increment和get都有指向createCounter(100) scope的引用。假設(shè)createCounter(100)沒有任何返回值,那么createCounter(100) scope不再被引用,于是就可以被垃圾回收。

但是createCounter(100)實(shí)際上是有返回值的,并且返回值被存儲(chǔ)在了myCounter中,所以對象之間的引用關(guān)系如下圖:

即使createCounter(100)已經(jīng)返回,但是其作用域仍在,并且只能被內(nèi)聯(lián)函數(shù)訪問。可以通過調(diào)用myCounter.increment() 或 myCounter.get()來直接訪問createCounter(100)的作用域。

當(dāng)myCounter.increment() 或 myCounter.get()被調(diào)用時(shí),新的作用域?qū)ο髸?huì)被創(chuàng)建,并且該作用域?qū)ο蟮母缸饔糜驅(qū)ο髸?huì)是當(dāng)前可以直接訪問的作用域?qū)ο蟆?/p>

調(diào)用get()時(shí),當(dāng)執(zhí)行到return counter時(shí),在get()所在的作用域并沒有找到對應(yīng)的標(biāo)示符,就會(huì)沿著作用域鏈往上找,直到找到變量counter,然后返回該變量。

多帶帶調(diào)用increment(5)時(shí),參數(shù)value保存在當(dāng)前的作用域?qū)ο蟆.?dāng)函數(shù)要訪問counter時(shí),沒有找到,于是沿著作用域鏈向上查找,在createCounter(100)的作用域找到了對應(yīng)的標(biāo)示符,increment()就會(huì)修改counter的值。除此之外,沒有其他方式來修改這個(gè)變量。閉包的強(qiáng)大也在于此,能夠存貯私有數(shù)據(jù)。

創(chuàng)建兩個(gè)函數(shù):myCounter1和myCounter2

//my_script.js
"use strict";
function createCounter(initial) {
/ ... see the code from previous example ... /
}

//-- create counter objects
var myCounter1 = createCounter(100);
var myCounter2 = createCounter(200);
關(guān)系圖如下

myCounter1.increment和myCounter2.increment的函數(shù)對象擁有著一樣的代碼以及一樣的屬性值(name,length等等),但是它們的[[scope]]指向的是不一樣的作用域?qū)ο蟆?/p> 五、參考

https://github.com/dwqs/blog/...

文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。

轉(zhuǎn)載請注明本文地址:http://m.specialneedsforspecialkids.com/yun/109795.html

相關(guān)文章

  • 【進(jìn)階2-1期】深入淺出圖解作用鏈和閉包

    摘要:本期推薦文章從作用域鏈談閉包,由于微信不能訪問外鏈,點(diǎn)擊閱讀原文就可以啦。推薦理由這是一篇譯文,深入淺出圖解作用域鏈,一步步深入介紹閉包。作用域鏈的頂端是全局對象,在全局環(huán)境中定義的變量就會(huì)綁定到全局對象中。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第6天。 本...

    levius 評論0 收藏0
  • 【進(jìn)階2-2期】JavaScript深入之從作用域鏈理解閉包

    摘要:使用上一篇文章的例子來說明下自由變量進(jìn)階期深入淺出圖解作用域鏈和閉包訪問外部的今天是今天是其中既不是參數(shù),也不是局部變量,所以是自由變量。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第二期,本周的主題是作用域閉包,今天是第7天。 本計(jì)劃一共28期,每期重點(diǎn)攻克一個(gè)面試重難點(diǎn),如果你還不了解本進(jìn)階計(jì)...

    simpleapples 評論0 收藏0
  • 【進(jìn)階2-3期】JavaScript深入閉包面試題解

    摘要:閉包面試題解由于作用域鏈機(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),如果你還不了...

    alanoddsoff 評論0 收藏0
  • 深入執(zhí)行環(huán)境、作用鏈和閉包

    摘要:執(zhí)行環(huán)境對象和作用域鏈執(zhí)行環(huán)境,又稱執(zhí)行上下文,是指一個(gè)函數(shù)在執(zhí)行的時(shí)候所能直接引用的變量等的一個(gè)集合。為了解釋作用域鏈的機(jī)制,我們再來引入一個(gè)屬性的概念。而函數(shù)的執(zhí)行環(huán)境對象作用域鏈保存了函數(shù)在執(zhí)行時(shí)能解析到的變量。 執(zhí)行環(huán)境對象和作用域鏈 執(zhí)行環(huán)境,又稱執(zhí)行上下文,是指一個(gè)函數(shù)在執(zhí)行的時(shí)候所能直接引用的變量等的一個(gè)集合。 在JavaScript引擎中,執(zhí)行環(huán)境是由一類特殊的對象——...

    gyl_coder 評論0 收藏0
  • 【進(jìn)階1-3期】JavaScript深入之內(nèi)存空間詳細(xì)圖解

    摘要:進(jìn)階期理解中的執(zhí)行上下文和執(zhí)行棧進(jìn)階期深入之執(zhí)行上下文棧和變量對象但是今天補(bǔ)充一個(gè)知識(shí)點(diǎn)某些情況下,調(diào)用堆棧中函數(shù)調(diào)用的數(shù)量超出了調(diào)用堆棧的實(shí)際大小,瀏覽器會(huì)拋出一個(gè)錯(cuò)誤終止運(yùn)行。 (關(guān)注福利,關(guān)注本公眾號(hào)回復(fù)[資料]領(lǐng)取優(yōu)質(zhì)前端視頻,包括Vue、React、Node源碼和實(shí)戰(zhàn)、面試指導(dǎo)) 本周正式開始前端進(jìn)階的第一期,本周的主題是調(diào)用堆棧,今天是第3天。 本計(jì)劃一共28期,每期重點(diǎn)攻...

    coordinate35 評論0 收藏0

發(fā)表評論

0條評論

最新活動(dòng)
閱讀需要支付1元查看
<