1、什么是作用域鏈?
JavaScript中,JavaScript里一切都是對(duì)象,包括函數(shù)。函數(shù)對(duì)象和其它對(duì)象一樣,擁有可以通過(guò)代碼訪問(wèn)的屬性和一系列僅供JavaScript引擎訪問(wèn)的內(nèi)部屬性。其中一個(gè)內(nèi)部屬性是作用域,包含了函數(shù)被創(chuàng)建的作用域中對(duì)象的集合,稱為函數(shù)的作用域鏈。
作用域(scope)
通常來(lái)說(shuō)一段程序代碼中使用的變量和函數(shù)并不總是可用的,限定其可用性的范圍即作用域,作用域的使用提高了程序邏輯的局部性,增強(qiáng)程序的可靠性,減少名字沖突。
作用域鏈作用(scope chain)
作用域鏈決定了哪些數(shù)據(jù)能被函數(shù)訪問(wèn)。當(dāng)一個(gè)函數(shù)創(chuàng)建后,它的作用域鏈會(huì)被創(chuàng)建此函數(shù)的作用域中可訪問(wèn)的數(shù)據(jù)對(duì)象填充。
var color = "blue";
function changeColor(){
if (color === "blue"){
color = "red";
} else {
color = "blue";
}
}
changeColor();
alert("Color is now " + color);
在這個(gè)簡(jiǎn)單的例子中,函數(shù) changeColor()的作用域鏈包含兩個(gè)對(duì)象:它自己的變量對(duì)象(其中定義著 arguments 對(duì)象)和全局環(huán)境的變量對(duì)象??梢栽诤瘮?shù)內(nèi)部訪問(wèn)變量 color,就是因?yàn)榭梢栽谶@個(gè)作用域鏈中找到它。
此外,在局部作用域中定義的變量可以在局部環(huán)境中與全局變量互換使用,如下面這個(gè)例子所示
var color = "blue";
function changeColor(){
var anotherColor = "red";
function swapColors(){
var tempColor = anotherColor;
anotherColor = color;
color = tempColor;
// 這里可以訪問(wèn) color、anotherColor 和 tempColor
}
// 這里可以訪問(wèn) color 和 anotherColor,但不能訪問(wèn) tempColor
swapColors();
}
// 這里只能訪問(wèn) color
changeColor();
以上代碼共涉及 3 個(gè)執(zhí)行環(huán)境:全局環(huán)境、changeColor()的局部環(huán)境和 swapColors()的局部環(huán)境。
全局環(huán)境中有一個(gè)變量 color 和一個(gè)函數(shù) changeColor()。
changeColor()的局部環(huán)境中有一個(gè)名為 anotherColor 的變量和一個(gè)名為 swapColors()的函數(shù),但它也可以訪問(wèn)全局環(huán)境中的變量 color。
swapColors()的局部環(huán)境中有一個(gè)變量 tempColor,該變量只能在這個(gè)環(huán)境中訪問(wèn)到。
無(wú)論全局環(huán)境還是 changeColor()的局部環(huán)境都無(wú)權(quán)訪問(wèn) tempColor。然而,在 swapColors()內(nèi)部則可以訪問(wèn)其他兩個(gè)環(huán)境中的所有變量,因?yàn)槟莾蓚€(gè)環(huán)境是它的父執(zhí)行環(huán)境。
下圖形象地展示了前面這個(gè)例子的作用域鏈。

圖中的矩形表示特定的執(zhí)行環(huán)境。其中,內(nèi)部環(huán)境可以通過(guò)作用域鏈訪問(wèn)所有的外部環(huán)境,但外部環(huán)境不能訪問(wèn)內(nèi)部環(huán)境中的任何變量和函數(shù)。這些環(huán)境之間的聯(lián)系是線性、有次序的。
每個(gè)環(huán)境都可以向上搜索作用域鏈,以查詢變量和函數(shù)名;但任何環(huán)境都不能通過(guò)向下搜索作用域鏈而進(jìn)入另一個(gè)執(zhí)行環(huán)境。對(duì)于這個(gè)例子中的 swapColors()而言,其作用域鏈中包含 3 個(gè)對(duì)象:swapColors()的變
量對(duì)象、changeColor()的變量對(duì)象和全局變量對(duì)象。swapColors()的局部環(huán)境開(kāi)始時(shí)會(huì)先在自己的變量對(duì)象中搜索變量和函數(shù)名,
如果搜索不到則再搜索上一級(jí)作用域鏈。changeColor()的作用域鏈中只包含兩個(gè)對(duì)象:它自己的變量對(duì)象和全局變量對(duì)象。這也就是說(shuō),它不能訪問(wèn) swapColors()的環(huán)境。
(參考閱讀《JS高級(jí)程序設(shè)計(jì)》這本書)