作用域
執(zhí)行環(huán)境:簡稱環(huán)境辨萍,定義了變量或函數(shù)有權(quán)訪問的其他數(shù)據(jù)谜嫉,決定了它們各自的行為闹击。
變量對(duì)象:每個(gè)執(zhí)行環(huán)境都有一個(gè)與之關(guān)聯(lián)的變量對(duì)象镶蹋,環(huán)境中定義的所有變量和函數(shù)都保存在這個(gè)對(duì)象中。這個(gè)對(duì)象無法通過代碼訪問赏半,但解析器在處理數(shù)據(jù)時(shí)會(huì)使用贺归。
環(huán)境棧:每個(gè)函數(shù)都有自己的執(zhí)行環(huán)境,當(dāng)執(zhí)行流進(jìn)入一個(gè)函數(shù)時(shí)除破,函數(shù)的環(huán)境就回被推入一個(gè)環(huán)境棧中牧氮,當(dāng)這個(gè)函數(shù)執(zhí)行后,棧將其環(huán)境彈出瑰枫。把控制權(quán)返回給之前的執(zhí)行環(huán)境踱葛。
作用域鏈:當(dāng)代碼在環(huán)境中執(zhí)行時(shí)丹莲,會(huì)創(chuàng)建變量對(duì)象的一個(gè)作用域鏈。作用域鏈的用途是保證對(duì)執(zhí)行環(huán)境有權(quán)訪問的所有變量和函數(shù)的有序訪問尸诽。作用域鏈的前端甥材,始終都是當(dāng)前執(zhí)行的代碼所在環(huán)境的變量對(duì)象。
作用域鏈中的下一個(gè)變量對(duì)象來自包含環(huán)境性含,而再下一個(gè)變量對(duì)象則來自下一個(gè)包含環(huán)境洲赵。這樣一直延續(xù)到全局執(zhí)行環(huán)境,全局執(zhí)行環(huán)境的變量對(duì)象始終都是作用域鏈中的最后一個(gè)對(duì)象
標(biāo)識(shí)符解析:標(biāo)識(shí)符解析是沿著作用域鏈一級(jí)一級(jí)地搜索標(biāo)識(shí)符過程商蕴。搜索過程始終從作用域鏈的前端開始叠萍,逐級(jí)向后回溯,直至找到標(biāo)識(shí)符绪商。(找不到會(huì)報(bào)錯(cuò))
延長作用域
:雖執(zhí)行環(huán)境的類型總共有兩種--全局和局部苛谷,但可以通過其他辦法來延長作用域。因?yàn)橛行┱Z句可以在作用域鏈前端臨時(shí)增加一個(gè)變量對(duì)象格郁,改變量對(duì)象會(huì)在代碼執(zhí)行后被移除腹殿。
try-catch 語句的catch塊
with 語句
這兩個(gè)語句都會(huì)在作用域鏈的前端添加一個(gè)變量對(duì)象。對(duì)With語句來說例书,會(huì)將指定的對(duì)象天劍到作用域鏈中锣尉。對(duì)Catch語句來說,會(huì)創(chuàng)建一個(gè)新的變量對(duì)象决采,其中包含的是被拋出的錯(cuò)誤對(duì)象的聲明自沧。
JS 中沒有塊級(jí)作用域
JavaScript 作用域不是以花括號(hào)包圍的塊級(jí)作用域,JS 中的變量作用域是有函數(shù)來決定的织狐。
em:
注意:在JS中可以初始化未聲明的變量暂幼。同時(shí)初始化未聲明的變量會(huì)將該變量添加全局變量中。
JS 函數(shù)作用域
JavaScript 的函數(shù)定義是可以嵌套的移迫,每一層是一個(gè)作用域旺嬉,變量搜索是從內(nèi)到外。
上述代碼不會(huì)輸出global厨埋,輸出undefined邪媳。這是JavaScript的一個(gè)特性,按照作用域搜索順序荡陷。在console.log函數(shù)訪問Scope變量時(shí)雨效,javaScript會(huì)先搜索函數(shù)f 的作用域,恰巧在f作用域里面搜索到scope變量废赞,所有上層作用域中定義的Scope就被屏蔽了徽龟。但執(zhí)行到console.log 語句時(shí),scope還沒被定義所以得到的就是undefined唉地。
JS 的作用域是靜態(tài)作用域
函數(shù)作用域的嵌套關(guān)系是定義時(shí)決定的据悔,而不是調(diào)用時(shí)決定的传透,又叫詞法作用域。這是因?yàn)樽饔糜虻那短钻P(guān)系可以在語法分析時(shí)確定极颓,而不必等到運(yùn)行時(shí)確定
輸出 top ?top 說明了作用域的嵌套關(guān)系不是在調(diào)用時(shí)確定的朱盐,而是在定義時(shí)確定的