一、作用域
作用域就是變量和函數(shù)的可訪問(wèn)范圍隘梨,控制著變量和函數(shù)的可見(jiàn)性與生命周期程癌,在JavaScript中變量的作用域有全局作用域和局部作用域。
變量沒(méi)有在函數(shù)內(nèi)聲明或者聲明的時(shí)候沒(méi)有帶var就是全局變量轴猎,擁有全局作用域嵌莉,window對(duì)象的所有屬性擁有全局作用域;在代碼任何地方都可以訪問(wèn)捻脖,函數(shù)內(nèi)部聲明并且以var修飾的變量就是局部變量锐峭,只能在函數(shù)體內(nèi)使用,函數(shù)的參數(shù)雖然沒(méi)有使用var但仍然是局部變量可婶。
var a=3; //全局變量
function fn(b){ //局部變量
c=2; //全局變量
var d=5; //局部變量
function subFn(){
var e=d; //父函數(shù)的局部變量對(duì)子函數(shù)可見(jiàn)
for(var i=0;i<3;i++){
console.write(i);
}
alert(i);//3, 在for循環(huán)內(nèi)聲明沿癞,循環(huán)外function內(nèi)仍然可見(jiàn),沒(méi)有塊作用域
}
}
alert(c); //在function內(nèi)聲明但不帶var修飾矛渴,仍然是全局變量
然而執(zhí)行環(huán)境(execution context)定義了變量或函數(shù)有權(quán)訪問(wèn)的其它數(shù)據(jù)椎扬,決定了它們的各自行為。每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象(variable object, VO)具温,執(zhí)行環(huán)境中定義的所有變量和函數(shù)都會(huì)保存在這個(gè)對(duì)象中蚕涤,解析器在處理數(shù)據(jù)的時(shí)候就會(huì)訪問(wèn)這個(gè)內(nèi)部對(duì)象。
全局執(zhí)行環(huán)境是最外層的一個(gè)執(zhí)行環(huán)境铣猩,在web瀏覽器中全局執(zhí)行環(huán)境是window對(duì)象揖铜,因此所有全局變量和函數(shù)都是作為window對(duì)象的屬性和放大創(chuàng)建的。
二达皿、作用域鏈
當(dāng)代碼在一個(gè)環(huán)境中執(zhí)行時(shí)天吓,會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈(scope chain,不簡(jiǎn)稱sc)來(lái)保證對(duì)執(zhí)行環(huán)境有權(quán)訪問(wèn)的變量和函數(shù)的有序訪問(wèn)。作用域第一個(gè)對(duì)象始終是當(dāng)前執(zhí)行代碼所在環(huán)境的變量對(duì)象(VO)
function a(x,y){
var b=x+y;
return b;
}
在函數(shù)a創(chuàng)建的時(shí)候它的作用域鏈填入全局對(duì)象,全局對(duì)象中有所有全局變量
如果執(zhí)行環(huán)境是函數(shù)峦椰,那么將其活動(dòng)對(duì)象(activation object, AO)作為作用域鏈第一個(gè)對(duì)象龄寞,第二個(gè)對(duì)象是包含環(huán)境,下一個(gè)是包含環(huán)境的包含環(huán)境汤功。萄焦。。冤竹。。
function a(x,y){
var b=x+y;
return b;
}
var tatal=a(5,10);
這時(shí)候 var total=a(5,10);語(yǔ)句的作用域鏈如下
在函數(shù)運(yùn)行過(guò)程中標(biāo)識(shí)符的解析是沿著作用域鏈一級(jí)一級(jí)搜索的過(guò)程茬射,從第一個(gè)對(duì)象開(kāi)始鹦蠕,逐級(jí)向后回溯,直到找到同名標(biāo)識(shí)符為止在抛,找到后不再繼續(xù)遍歷钟病,找不到就報(bào)錯(cuò)。