為了更好的理解作用域鏈,先做些準(zhǔn)備工作
1.作用域
在JavaScript中,我們可以將作用域定義為一套規(guī)則,這套規(guī)則用來管理引擎如何在當(dāng)前作用域以及嵌套的子作用域中根據(jù)標(biāo)識符(這里的標(biāo)識符,指的是變量名或者函數(shù)名)名稱進(jìn)行變量查找。
javascript中的作用域有全局作用域和局部作用域兩種,局部作用域又稱為函數(shù)作用域。
全局作用域
在代碼中任何地方都能訪問到的對象擁有全局作用域
var a = "tsrot";
function hello(){
alert(a);
}
function sayHello(){
hello();
}
alert(a); //能訪問到tsrot
hello(); //能訪問到tsrot
sayHello(); //能訪問到hello函數(shù),然后也能訪問到tsrot
局部作用域(函數(shù)作用域)
局部作用域在函數(shù)內(nèi)創(chuàng)建,在函數(shù)內(nèi)可訪問,函數(shù)外不可訪問。
function hello(){
var a = "tsrot";
alert(a);
}
hello(); //函數(shù)內(nèi)可訪問到tsrot
alert(a); //error not defined
作用域鏈
函數(shù)在調(diào)用激活時(shí),會(huì)開始創(chuàng)建對應(yīng)的執(zhí)行上下文,在執(zhí)行上下文生成的過程中,變量對象,作用域鏈,以及this的值會(huì)分別被確定。
作用域鏈,是由當(dāng)前環(huán)境與上層環(huán)境的一系列變量對象組成,它保證了當(dāng)前執(zhí)行環(huán)境對符合訪問權(quán)限的變量和函數(shù)的有序訪問。
作用域鏈指示了函數(shù)執(zhí)行時(shí)按照什么樣順序去訪問需要的變量,
具體過程如下例子:
var a = 20;
function test() {
var b = a + 10;
function innerTest() {
var c = 10;
return b + c;
}
return innerTest();
}
test();
在上面的例子中,全局,函數(shù)test,函數(shù)innerTest的執(zhí)行上下文先后創(chuàng)建。我們設(shè)定他們的變量對象分別為VO(global),VO(test), VO(innerTest)。而innerTest的作用域鏈,則同時(shí)包含了這三個(gè)變量對象,所以innerTest的執(zhí)行上下文生成的作用域鏈可如下表示。
VO(innerTest) ==> VO(test) ==> VO(global)
先在VO(innerTest)里面找到c,但沒有找到b,于是向上一級找,在 VO(test)里面找到b,最后在全局VO(global)找到a
即函數(shù)在訪問變量時(shí),先在當(dāng)前執(zhí)行上下文尋找,找不到再向上一級尋找,直至全局上下文。