JavaScript-做用域、塊級做用域、上下文、執行上下文、做用域鏈

1、做用域

在 JavaScript 中, 做用域(scope,或譯有效範圍)就是變量和函數的 可訪問範圍,即做用域控制着變量和函數的 可見性生命週期

2、全局/局部做用域

2.1 全局做用域(Global Scope)

(1)不在任何函數內定義的變量就具備全局做用域。javascript

(2)實際上,JavaScript默認有一個全局對象window,全局做用域的變量實際上被綁定到window的一個屬性java

全局做用域

(3)window對象的內置屬性都擁有全局做用域,例如 window.name、window.location、window.top 等。web

2.2 局部做用域(Local Scope)

(1)JavaScript的做用域是經過函數來定義的,在一個函數中定義的變量只對這個函數內部可見,稱爲函數(局部)做用域segmentfault

3、全局/局部變量

變量可以被定義在局部或者全局做用域,這致使運行時 變量的訪問來自不一樣的做用域

3.1 全局變量

(1)在函數定義外聲明的變量是全局變量。 瀏覽器

(2)全局變量有 全局做用域,它的值可在整個程序中訪問和修改函數

(3)若是變量在函數內沒有聲明(沒有使用 var 關鍵字),該變量爲全局變量。this

3.2 局部變量

(1)在函數定義內聲明的變量是局部變量。spa

(2)由於局部變量只做用於函數內,因此不一樣的函數可使用相同名稱的變量code

(3)每當執行函數時,都會建立銷燬該變量,且沒法經過函數以外的任何代碼訪問該變量。對象

(4)函數外沒法訪問函數內的變量,函數內卻能夠訪問函數外的變量。

4、全局變量

一、在 函數定義外聲明的變量是全局變量;全局變量有全局做用域,它的 值可在整個程序中訪問和修改

全局變量

二、若是 變量在函數內沒有聲明(沒有使用 var 關鍵字),該變量爲全局變量。

全局變量

5、局部變量

一、由於局部變量只做用於函數內,因此 不一樣的函數可使用相同名稱的變量

局部變量

二、每當執行函數時,都會 建立銷燬該變量,且沒法經過函數以外的任何代碼訪問該變量。

局部變量

三、 函數外沒法訪問函數內的變量,函數內卻能夠訪問函數外的變量。

局部變量

6、塊級做用域

6.1 概念

塊級做用域指在If語句,switch語句,循環語句等語句塊中定義變量,這意味着變量 不能在語句塊以外被訪問

6.2 var 不支持塊級做用域

(1)在If等語句塊中,定義的變量從屬於該塊所在的做用域,和函數不一樣,他們不會建立新的做用域。

var

6.3 let和const

(1)爲了解決塊級做用域,ES6引入了 letconst 關鍵字,能夠聲明一個塊級做用域的變量

let和const

(2)全局做用域的生存週期與上述應用相同。局部做用域只在該函數調用執行期間存在。

7、上下文 vs 做用域

(1)首先須要說明的是上下文和做用域是不一樣的概念

(2)每一個函數調用都有與之相關的做用域和上下文。從根本上說,做用域是基於函數,而上下文是基於對象

(3)做用域是和每次函數調用時變量的訪問有關,而且每次調用都是獨立的。上下文老是關鍵字 this 的值,是調用當前可執行代碼的對象的引用。

8、「this」 上下文

(1)上下文一般是取決於一個函數如何被調用。當函數做爲對象的方法被調用時,this 指向調用方法的對象

上下文

(2)當調用一個函數時,經過 new 操做符建立一個對象的實例,當以這種方式調用時,this 指向新建立的實例

上下文

(3)當調用一個未綁定函數,this 默認指向全局上下文或者瀏覽器中的window對象。然而若是函數在嚴格模式下被執行(「use strict」),this 默認指向 undefined

9、執行上下文

(1)當函數執行時,會建立一個稱爲執行上下文的內部對象(可理解爲做用域,不是前面討論的上下文)。一個執行上下文定義了一個函數執行時的環境

(2)函數每次執行時對應的執行上下文都是獨一無二的,因此屢次調用一個函數會致使建立多個執行上下文。

(3)當javascript代碼文件被瀏覽器載入後,默認最早進入的是一個全局的執行上下文。當在全局上下文中調用執行一個函數時,程序流就進入該被調用函數內,此時引擎就會爲該函數建立一個新的執行上下文,而且將其壓入到執行棧頂部(做用域鏈)。瀏覽器老是執行位於執行棧頂部的當前執行上下文,一旦執行完畢,該執行上下文就會從執行棧頂部彈出,而且控制權將進入其下的執行上下文。這樣,執行棧中的執行上下文就會被依次執行而且彈出,直到回到全局的執行上下文。

10、做用域鏈

(1)在JavaScript中,函數也是對象,對象中有些屬性咱們能夠訪問,但有些不能夠(訪問),這些屬性僅供JavaScript引擎存取,[[scope]]就是其中一個。

(2)[[scope]]指的就是咱們所說的做用域,其中存儲了執行上下文的集合。

(3)[[scope]]中所存儲的執行上下文對象的集合,這個集合呈鏈式連接,咱們把這種鏈式連接叫作做用域鏈。

10.1 示例

執行期上下文

(1)運行示例代碼將會致使嵌套的函數被從上倒下執行,一直到 fourth 函數,此時做用域鏈從上到下爲: fourth, third, second, first, global。

(2)fourth 函數可以訪問全局變量和任何定義在first,second和third函數中的變量(和訪問本身的變量同樣)。

(3)一旦fourth函數執行完成,其就會從做用域鏈頂部移除,而且執行權會返回到third函數。這個過程一直持續到全部代碼完成執行。

10.2 攀爬做用域鏈

(1)當不一樣執行上下文之間存在 變量命名衝突,能夠經過攀爬做用域鏈解決(從頂部到底部)。這也就是說
在最內層函數(執行棧頂部的執行上下文)中,具備相同變量名稱的變量將具備較高優先級。

(2)簡單的說,每次試圖訪問函數執行上下文中的變量時,查找進程老是從本身的變量對象開始。若是在本身的變量對象中沒發現要查找的變量,繼續搜索做用域鏈。他將攀爬做用域鏈檢查每個執行上下文的變量對象,去尋找和變量名稱匹配的值

閱讀更多

個人博客即將搬運同步至騰訊雲+社區,邀請你們一同入駐:https://cloud.tencent.com/dev...

相關文章
相關標籤/搜索