03------JS函數高級之執行上下文與執行上下文棧

執行上下文與執行上下文棧

1.變量提升與函數提升

變量聲明提升

  • 通過var定義(聲明)的變量,在定義語句之前就可以訪問到
  • 值:undefined

函數聲明提升

  • 通過function聲明的函數,在之前就可以直接調用
  • 值:函數定義(對象)
var a = 3
function fn() {
	console.log(a) // undefined
	var a = 4
}
fn()
console.log(b) // unfefined 變量提升
fn2() //可調用 函數提升
var b = 3
function fn2() {
	console.log('fn2()')
}

問題:變量提升和函數提升是如何產生的?
變量提升和函數提升引申出執行上下文執行上下文棧
2.執行上下文

全局執行上下文

  • 在執行全局代碼前將window確定爲全局執行上下文

  • 對全局數據進行預處理

    • var定義的全部變量---->undefined,添加爲window的屬性
    • function聲明的全局函數---->賦值(fun),添加爲window的方法
    • this---->賦值(window)
  • 開始執行全局代碼

函數執行上下文(虛擬的,存在於棧中)

  • 在調用函數,準備執行函數體之前,創建對應的函數執行上下文對象

  • 對局部數據進行預處理

    • 形參變量---->賦值(實參)---->添加爲執行上下文的屬性
    • arguments---->賦值(實參列表),添加爲執行上下文的屬性
    • var定義的局部變量---->undefined,添加執行上下文的屬性
    • function聲明的函數---->賦值(fun),添加執行上下文的屬性
    • this---->賦值(調用函數的對象)
  • 開始執行函數體代碼

// 函數執行上下文
function fn(a1) {
	console.log(a1) // 2
	console.log(a2) // undefined
	a3() // a3()
	console.log(this) // window
	console.log(arguments) // 僞數組(2, 3)
	
	var a2 = 3
	function a3() {
		console.log('a3()')
	}
}
fn(2, 3)

3.執行上下文棧

  • 在全局代碼執行前,JS引擎就會創建一個棧來存儲管理所有的執行上下文對象
  • 在全局執行上下文(window)確定後,將其添加到棧中(壓棧)
  • 在函數執行上下文創建後,將其添加到棧中(壓棧)
  • 在當前函數執行完後,將棧頂的對象移除(出棧)
  • 當所有的代碼執行完後,棧中只剩下window
<script type="text/javascript">
//1.進入全局執行上下文
var a = 10
var bar = function (x) {
	var b = 5
	foo(x + b) // 3.進入foo執行上下文
}
var foo = function (y) {
	var c = 5
	console.log(a + c + y)
}
bar(10) // 2.進入bar函數執行上下文
</script>

圖解
在這裏插入圖片描述
注意:棧底的執行上下文一定是window,總在底部
面試題:
1).

<script type="text/javascript">
console.log('gb:' + i)
var i = 1
foo(1)
function foo(i) {
	if(i == 4) {
		return
	}
	console.log('fb:' + i)
	foo(i + 1) // 遞歸函數
	console.log('fe: ' + i)
}
console.log('ge:' + i)
// 1.依次輸出什麼?
// gb:undefined
// fb:1
// fb:2
// fb:3
// fe:3
// fe:2
// fe:1
// fe:1
// 2.整個過程中產生了幾個執行上下文? 5個
</script>

2).

// 先執行變量提升,再執行函數提升
function a() {}
var a;
console.log(typeof a) // 'function'

if(!(b in window)) {
	var b = 1
}
console.log(b) // undefined

3).

var c = 1
function c(c) {
	console.log(c)
}
c(2) //報錯 c不是function 變量提升
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章