先看一段代碼:
console.log(a); //在變量a定義之前隘庄,直接輸出a矾策,輸出a的值是多少?會(huì)有報(bào)錯(cuò)嗎峭沦?
var a = 1;
console.log(a); //定義之后贾虽,肯定會(huì)正常輸出a的值
來看一下結(jié)果:
image.png
看到這小伙伴們是否有疑問,在變量a定義之前吼鱼,進(jìn)行打印a的操作蓬豁,竟然沒有報(bào)錯(cuò),輸出的結(jié)果是undefined菇肃,這是為什么呢地粪?我們學(xué)習(xí)js的時(shí)候,知道變量未定義是不能直接使用的琐谤,如下圖蟆技,那么這個(gè)地方為什么沒有報(bào)錯(cuò)呢?
image.png
很多編程語言在執(zhí)行代碼之前會(huì)進(jìn)行代碼的預(yù)處理斗忌,同樣js亦是如此质礼。在代碼執(zhí)行之前,會(huì)有一個(gè)執(zhí)行上下文對(duì)象织阳,在這個(gè)過程中會(huì)預(yù)先對(duì)代碼進(jìn)行處理眶蕉,根據(jù)代碼種類的不同,映射出兩種不同的執(zhí)行上下文對(duì)象:
1. 代碼分類或執(zhí)行上下文的種類
- 全局代碼 -------->>全局執(zhí)行上下文
- 局部代碼/函數(shù)碼 -------->>函數(shù)執(zhí)行上下文
2. 全局執(zhí)行上下文-全局代碼的執(zhí)行處理
- 在全局代碼執(zhí)行之前唧躲,會(huì)有一個(gè)執(zhí)行上下文對(duì)象造挽,這個(gè)對(duì)象被稱之為“全局上下文”對(duì)象碱璃,這個(gè)對(duì)象是真實(shí)存在的,對(duì)應(yīng)的是Window對(duì)象;
- 在全局代碼執(zhí)行之前會(huì)進(jìn)行代碼的預(yù)處理饭入,包括:
- 找到var對(duì)應(yīng)的變量嵌器,并將其賦值為undefined,添加該變量為window對(duì)象谐丢。(其實(shí)不是賦值嘴秸,window中添加該變量較為準(zhǔn)確)
- 找到function聲明的全局函數(shù),并且賦值為函數(shù)地址庇谆,并添加為window的全局方法
- 將this賦值為window
- ==>執(zhí)行全局代碼
3.函數(shù)執(zhí)行上下文-函數(shù)代碼的執(zhí)行處理
- 在調(diào)用函數(shù)時(shí),執(zhí)行函數(shù)之前會(huì)創(chuàng)建函數(shù)執(zhí)行上下文對(duì)象凭疮,這個(gè)對(duì)象是虛擬的饭耳,存在于棧當(dāng)中
- 在函數(shù)體執(zhí)行之前,進(jìn)行函數(shù)數(shù)據(jù)的預(yù)處理
- 將函數(shù)的形參賦值為實(shí)參执解,并添加到上下文對(duì)象的屬性當(dāng)中
- 將arguments賦值為實(shí)參列表寞肖,添加到函數(shù)執(zhí)行上下文屬性當(dāng)中
-找到var聲明的變量,并將其添加到函數(shù)執(zhí)行上下文對(duì)象當(dāng)中
-將內(nèi)部function聲明的函數(shù)賦值為fun衰腌,添加到上下文對(duì)象當(dāng)中 - 將this賦值為調(diào)用該函數(shù)的對(duì)象
- ==>執(zhí)行函數(shù)代碼