摘要:每一個(gè)執(zhí)行上下文可以訪問的對(duì)象包括自身的作用域和父執(zhí)行上下文的作用域和父父執(zhí)行上下文作用域直到全局作用域,這就產(chǎn)生了作用域鏈。語句結(jié)束后,作用域鏈恢復(fù)正常。
0、自己理解
代碼執(zhí)行或函數(shù)調(diào)用生成執(zhí)行上下文(只有當(dāng)前執(zhí)行上下文有執(zhí)行權(quán)),該執(zhí)行上下文內(nèi)只能訪問當(dāng)前執(zhí)行上下文的變量、函數(shù)和上一級(jí)執(zhí)行上下文中的變量、函數(shù),激活下一個(gè)執(zhí)行上下文的時(shí)候執(zhí)行權(quán)轉(zhuǎn)移到新的執(zhí)行上下文,形成執(zhí)行上下文棧。
作用域是當(dāng)前執(zhí)行上下文中能訪問的變量、函數(shù)的集合,執(zhí)行上下文中只能訪問當(dāng)前作用域和其上執(zhí)行上下文的作用域,由此形成作用域鏈
1、執(zhí)行上下文(棧)每一次代碼執(zhí)行和函數(shù)調(diào)用都會(huì)產(chǎn)生一個(gè)執(zhí)行環(huán)境,稱為執(zhí)行上下文(context stack)。
一個(gè)執(zhí)行上下文caller又可以激活(調(diào)用)另一個(gè)執(zhí)行上下文callee,這時(shí)caller會(huì)暫停自身的執(zhí)行把控制權(quán)交給callee進(jìn)入callee的執(zhí)行上下文,callee執(zhí)行完畢后將控制權(quán)交回caller,callee可以用return或者拋出Exception來結(jié)束自己的執(zhí)行。
多個(gè)執(zhí)行上下文會(huì)形成執(zhí)行上下文棧,最頂層是當(dāng)前執(zhí)行上下文,底層是全局執(zhí)行上下文。
作用域(scope chain)是每一個(gè)執(zhí)行上下文自身持有的活動(dòng)對(duì)象的集合,如在本執(zhí)行上下文中聲明的變量和函數(shù)以及方法參數(shù)傳入的對(duì)象。
每一個(gè)執(zhí)行上下文可以訪問的對(duì)象包括自身的作用域和父執(zhí)行上下文的作用域和父父執(zhí)行上下文作用域直到全局作用域,這就產(chǎn)生了作用域鏈。作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問。
作用域鏈的工作原理跟原型鏈?zhǔn)窒嗨疲喝绻旧淼淖饔糜蛑胁檎也坏綐?biāo)識(shí)符,那么就查找父作用域,直到頂層。
目前假設(shè)作用域的聯(lián)動(dòng)是用的__parent__對(duì)象,它指向作用域鏈的下一個(gè)對(duì)象。(在ES5中,確實(shí)有一個(gè)outer鏈接)
全局上下文的作用域包含Object.prototype中的對(duì)象,with和catch會(huì)改變作用域鏈,在with中,查詢__parent__之前會(huì)先去查詢__proto__,會(huì)使作用域鏈增大。
2.1 作用域鏈中的名稱解析順序javascript中一個(gè)名字(name)以四種方式進(jìn)入作用域(scope),其優(yōu)先級(jí)順序如下:
語言內(nèi)置:所有的作用域中都有 this 和 arguments 關(guān)鍵字
形式參數(shù):函數(shù)的參數(shù)在函數(shù)作用域中都是有效的
函數(shù)聲明:形如function foo() {}
變量聲明:形如var bar;
名字聲明的優(yōu)先級(jí)如上所示,也就是說如果一個(gè)變量的名字與函數(shù)的名字相同,那么函數(shù)的名字會(huì)覆蓋變量的名字,無論其在代碼中的順序如何;形式參數(shù)會(huì)覆蓋變量聲明。但名字的初始化卻是按其在代碼中書寫的順序進(jìn)行的,不受以上優(yōu)先級(jí)的影響。
(function(){ var foo; console.log(typeof foo); //function function foo(){} foo = "foo"; console.log(typeof foo); //string })();
如果形參中有多個(gè)同名變量,那么最后一個(gè)同名參數(shù)會(huì)覆蓋其他同名參數(shù),即使最后一個(gè)同名參數(shù)未定義;以上的名字解析優(yōu)先級(jí)存在例外,比如可以覆蓋語言內(nèi)置的名字arguments。
2.2 with改變作用域鏈with語句主要用來臨時(shí)擴(kuò)展作用域鏈,將語句中的對(duì)象添加到作用域的頭部。
person={name:"yhb",age:22,height:175,wife:{name:"lwy",age:21}}; with(person.wife){ console.log(name); }
with語句將person.wife添加到當(dāng)前作用域鏈的頭部,所以輸出的就是lwy。with語句結(jié)束后,作用域鏈恢復(fù)正常。
3、二維作用域鏈查找源于ECMAScript的原型特性。如果一個(gè)屬性在對(duì)象中沒有直接找到,查詢將在原型鏈中繼續(xù)。即常說的二維鏈查找。
作用域鏈環(huán)節(jié);
每個(gè)作用域鏈-深入到原型鏈環(huán)節(jié)
網(wǎng)上的帖子大多深淺不一,甚至有些前后矛盾,在下的文章都是學(xué)習(xí)過程中的總結(jié),如果發(fā)現(xiàn)錯(cuò)誤,歡迎留言指出~
參考:
1、執(zhí)行上下文(棧)/作用域(鏈)/with
2、Js 作用域與作用域鏈與執(zhí)行上下文不得不說的故事
PS:歡迎大家關(guān)注我的公眾號(hào)【前端下午茶】,一起加油吧~
另外可以加入「前端下午茶交流群」微信群,長按識(shí)別下面二維碼即可加我好友,備注加群,我拉你入群~
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://specialneedsforspecialkids.com/yun/92024.html
摘要:在之前我們根絕對(duì)象的原型說過了的原型鏈,那么同樣的萬物皆對(duì)象,函數(shù)也同樣存在這么一個(gè)鏈?zhǔn)降年P(guān)系,就是函數(shù)的作用域鏈作用域鏈?zhǔn)紫认葋砘仡櫼幌轮爸v到的原型鏈的尋找機(jī)制,就是實(shí)例會(huì)先從本身開始找,沒有的話會(huì)一級(jí)一級(jí)的網(wǎng)上翻,直到頂端沒有就會(huì)報(bào)一 在之前我們根絕對(duì)象的原型說過了js的原型鏈,那么同樣的js 萬物皆對(duì)象,函數(shù)也同樣存在這么一個(gè)鏈?zhǔn)降年P(guān)系,就是函數(shù)的作用域鏈 作用域鏈 首先先來回...
摘要:開篇作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)作用域和作用域鏈就是個(gè)繞不開的話題。這樣由多個(gè)執(zhí)行上下文的變量對(duì)象構(gòu)成的鏈表就叫做作用域鏈。這時(shí)候執(zhí)行上下文的作用域鏈,我們命名為至此,作用域鏈創(chuàng)建完畢。 開篇 作用域是每種計(jì)算機(jī)語言最重要的基礎(chǔ)之一,因此要想深入的學(xué)習(xí)JavaScript,作用域和作用域鏈就是個(gè)繞不開的話題。 在《深入學(xué)習(xí)js之—-執(zhí)行上下文棧》中我們提到...
摘要:思考題在深入學(xué)習(xí)之詞法作用域和動(dòng)態(tài)作用域中,提出這樣一道思考題思考題一思考題二兩段代碼都會(huì)打印但是還是有些許差異的,本文就詳細(xì)的解析執(zhí)行上下文棧和執(zhí)行上下文的具體變化過程。 在《深入學(xué)習(xí)js之——執(zhí)行上下文棧》中說過,當(dāng)JavaScript代碼執(zhí)行一段可執(zhí)行代碼(executable code)時(shí),會(huì)創(chuàng)建對(duì)應(yīng)的執(zhí)行上下文(execution context) 對(duì)于每一個(gè)執(zhí)行上下文,都有...
摘要:執(zhí)行上下文棧首先我們先了解一下什么是執(zhí)行上下文棧。那么隨著我們的執(zhí)行上下文數(shù)量的增加,引擎又如何去管理這些執(zhí)行上下文呢這時(shí)便有了執(zhí)行上下文棧。這樣由多個(gè)執(zhí)行上下文的變量對(duì)象構(gòu)成的鏈表就叫做作用域鏈。 執(zhí)行上下文棧 首先我們先了解一下什么是執(zhí)行上下文棧(Execution context stack)。 showImg(https://segmentfault.com/img/remot...
摘要:執(zhí)行上下文作用域鏈和內(nèi)部機(jī)制一執(zhí)行上下文執(zhí)行上下文是代碼的執(zhí)行環(huán)境,它包括的值變量對(duì)象和函數(shù)。創(chuàng)建作用域鏈一旦可變對(duì)象創(chuàng)建完,引擎就開始初始化作用域鏈。 執(zhí)行上下文、作用域鏈和JS內(nèi)部機(jī)制(Execution context, Scope chain and JavaScript internals) 一、執(zhí)行上下文 執(zhí)行上下文(Execution context EC)是js代碼的執(zhí)...
閱讀 2815·2021-10-13 09:48
閱讀 3776·2021-10-13 09:39
閱讀 3586·2021-09-22 16:04
閱讀 1816·2021-09-03 10:48
閱讀 837·2021-08-03 14:04
閱讀 2358·2019-08-29 15:18
閱讀 3400·2019-08-26 12:19
閱讀 2869·2019-08-26 12:08