一篇帶你了解JS 執行上下文與作用域
JavaScript中的執行上下文是指JavaScript代碼執行的環境,它包括變量、函數、作用域和this等元素。在JavaScript中,每當函數執行時,都會創建一個新的執行上下文。
執行上下文分為全局執行上下文和函數執行上下文兩種。
全局執行上下文
全局執行上下文是在頁面加載時創建的,它是整個JavaScript代碼的最外層環境,包含了所有的全局變量、函數和this等元素。
函數執行上下文
函數執行上下文是在函數被調用時創建的,它包含了函數內部的變量、函數和this等元素。每當函數被調用時,都會創建一個新的函數執行上下文。
函數執行上下文包括三個重要的元素:
- 變量對象(Variable Object,VO):包含了函數內部的變量和函數聲明。
- 作用域鏈(Scope Chain):用于解決變量訪問的問題,它是一個由多個執行上下文的變量對象組成的鏈式結構。
- this指針:指向函數被調用時的當前對象。
執行上下文的創建過程分為兩個階段:創建階段和代碼執行階段。
創建階段
在創建階段,JavaScript引擎會進行以下操作:
- 創建變量對象:函數執行上下文中的變量對象包括所有的函數參數、函數聲明和變量聲明等。
- 建立作用域鏈:JavaScript引擎會將當前執行上下文的變量對象添加到作用域鏈的最前端。
- 確定this指針:this指針的值取決于函數被調用時的環境。
代碼執行階段
在代碼執行階段,JavaScript引擎會按照代碼的順序執行代碼,并將變量的值存儲在變量對象中。
需要注意的是,JavaScript中的變量提升現象是由執行上下文的創建階段所導致的。在創建階段中,JavaScript引擎會將變量聲明提升到當前執行上下文的頂部,因此在代碼執行階段前就可以訪問到變量。
當代碼運行時,會產生對應的運行環境,在這個環境中,所有的變量都會被實現提出來(變量提升),有的直接賦值,有的默認賦值,有點默認值 undefined ,代碼從上而下開始執行,就叫做執行上下文。
變量提升
foo // undefined
var foo = function () {
console.log('foo1')
}
foo() // foo1, foo賦值
var foo = function () {
console.log('foo2')
}
foo() // foo2, foo 賦值
函數提升
foo() // foo2
function () {
console.log('foo1')
}
foo() // foo2
function foo () {
console.log('foo2')
}
foo() // foo2
聲明優先級,函數 > 變量
foo() // foo2
var foo = function () {
console.log('foo1')
}
foo() // foo1, foo 重新賦值
function foo () {
console.log('foo2')
}
foo() // foo1
總之,執行上下文是JavaScript代碼執行的環境,包括變量對象、作用域鏈和this等元素。了解執行上下文的創建過程和作用可以幫助開發者更好地理解和調試JavaScript代碼。