js作用域:函數(shù)作用域赋除、全局作用域
作用域鏈:由當(dāng)前環(huán)境與上層環(huán)境的一系列變量對象組成,它保證了當(dāng)前執(zhí)行環(huán)境對符合訪問權(quán)限的變量和函數(shù)的有序訪問戳护。
舉個(gè)例子:
function demo(){
var a=10;
}
demo();
console.log(a);
解析
調(diào)用demo時(shí)開始創(chuàng)建demo的上下文執(zhí)行環(huán)境金抡,創(chuàng)建變量對象VO={a:undefined},創(chuàng)建作用域鏈:[VO(demo),VO(global)]腌且。
執(zhí)行demo上下文階段梗肝,變量a賦值為10,執(zhí)行結(jié)束,demo函數(shù)出棧铺董,上下文被銷毀巫击。全局作用域中沒有a對象,訪問拋錯(cuò)精续。
VM80:5 Uncaught ReferenceError: a is not defined
at <anonymous>:5:13
閉包中的作用域
閉包:閉包是指有權(quán)訪問另一個(gè)函數(shù)作用域中的變量函數(shù)坝锰;
閉包的功能:可以訪問外部函數(shù),維持函數(shù)作用域重付。
function demo2(){
var a=10;
function foo(){
return a;
}
return foo;
}
console.log(demo2()());
demo2()創(chuàng)建demo的上下文顷级,創(chuàng)建變量對象VO={a:undefined,foo:<>},創(chuàng)建作用域鏈[VO(demo2) VO(global)];執(zhí)行階段a賦值10,返回foo函數(shù)确垫。
demo()()即foo(),foo的作用域鏈為:[VO(foo),VO(demo2),VO(global)]愕把,foo函數(shù)可以訪問函數(shù)demo2中的變量,也可以訪問全局變量森爽。foo函數(shù)執(zhí)行return a恨豁;
demo2()執(zhí)行后返回foo,此時(shí)demo已經(jīng)執(zhí)行結(jié)束了,其上下文應(yīng)該被銷毀爬迟,a應(yīng)該被銷毀橘蜜。但是因?yàn)閞eturn foo的存在,導(dǎo)致foo函數(shù)的執(zhí)行上下文被保留,而函數(shù)demo2中的執(zhí)行上下文中包含了foo计福,所以demo的執(zhí)行上下文不能被銷毀跌捆,可以說閉包foo維持了demo2的作用域,a變量也就可以繼續(xù)訪問了象颖。