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