作用域
名詞概念
- 引擎
負(fù)責(zé)整個(gè)js程序的編譯及執(zhí)行過(guò)程 - 編譯器
負(fù)責(zé)語(yǔ)法分析及代碼生成 - 作用域
負(fù)責(zé)收集并維護(hù)所有聲明的標(biāo)識(shí)符(變量)婶熬,確定當(dāng)前執(zhí)行的代碼對(duì)這些標(biāo)識(shí)符的訪問(wèn)權(quán)限
詞法作用域睬辐、函數(shù)作用域和塊作用域
JavaScript在預(yù)編譯后執(zhí)行代碼時(shí)鸠窗,引擎就會(huì)對(duì)其進(jìn)行查詢科盛,查詢分為:
LHS:Left-Hand-Side
RHS:Right-Hand-Side
即賦值的左側(cè)和右側(cè):當(dāng)出現(xiàn)在賦值操作的左側(cè)時(shí)進(jìn)行LHS查詢遵馆,出現(xiàn)在右側(cè)時(shí)進(jìn)行RHS查詢数尿。
RHS查詢就相當(dāng)于簡(jiǎn)單地查找某個(gè)變量的值
LHS查詢是試圖找到變量的容器本身躏敢,從而可以對(duì)其進(jìn)行賦值。
function foo(a) {
var b = a;
return a + b;
}
var c = foo( 2 );
//3處LHS 1.var c= 2. foo(a) a形參的賦值 3.var b =
//4處RHS 1.foo(2) 2.=a 3.a+ 4.+b
作用域嵌套
當(dāng)一個(gè)塊或函數(shù)嵌套在另一個(gè)塊或函數(shù)中時(shí)喉钢,就發(fā)生了作用域的嵌套姆打。因此,在當(dāng)前作用
域中無(wú)法找到某個(gè)變量時(shí)肠虽,引擎就會(huì)在外層嵌套的作用域中繼續(xù)查找幔戏,直到找到該變量,
或抵達(dá)最外層的作用域(也就是全局作用域)為止税课。
作用域分類
- 作用域分為動(dòng)態(tài)作用域和詞法作用域
js屬于詞法作用域闲延,下面的代碼展示出兩者不同:
如果是按照動(dòng)態(tài)作用域執(zhí)行痊剖,輸出應(yīng)該是找調(diào)用foo()的作用域,也就是bar()作用域中的a變量輸出3垒玲,換而言之陆馁,動(dòng)態(tài)作用域不關(guān)心在何處聲明,只關(guān)心在何處調(diào)用合愈;而詞法作用域讓 foo() 中的 a 通過(guò) RHS 引用到了全局作用域中的 a叮贩,因此會(huì)輸出 2。
function foo() {
console.log(a); // 2
}
function bar() {
var a = 3;
foo();
}
var a = 2;
bar();
- js中的作用域又分為函數(shù)作用域和塊作用域
閉包
當(dāng)函數(shù)可以記住并訪問(wèn)所在的詞法作用域時(shí)佛析,就產(chǎn)生了閉包益老,即使函數(shù)是在當(dāng)前詞法作用域之外執(zhí)行。
function foo() {
var a = 2;
function bar() {
console.log( a ); // 2
}
bar();
}
foo();
基于詞法作用域的查找規(guī)則寸莫,函數(shù)bar() 可以訪問(wèn)外部作用域中的變量 a