You-Dont-Know-JS詞法作用域及兩種常見(jiàn)的模型學(xué)習(xí)文檔
Lexical Scope - 詞法作用域
作用域有兩種常見(jiàn)的模型,一種叫做 詞法作用域 Lexical Scope,一種叫做動(dòng)態(tài)作用域 Dynamic Scope。其中詞法作用域更常見(jiàn),被大多數(shù)語(yǔ)言采用,包括javascript。
詞法分析
詞法分析過(guò)程Lex-time,是指系統(tǒng)講源碼字符串解讀成有含義的token的過(guò)程。詞法作用域就是說(shuō)在詞法分析過(guò)程中指派的作用域,詞法作用域在詞法解析過(guò)程中就已經(jīng)定死了。
依然有一些手段能在詞法解析之后改變?cè)~法作用域,但這些做法并不推薦。使用關(guān)鍵詞eval, with,會(huì)產(chǎn)生性能問(wèn)題。
考慮如下代碼:

- 氣泡(作用域) 1 :即全局作用域,包含變量
foo - 氣泡(作用域) 2 :foo的作用域,包含變量
a,bar,b - 氣泡(作用域) 3 :bar的作用域,包含變量
c
bar 作用域里完整的包含了foo 的作用域, 因?yàn)閎ar 是在foo中定義的,產(chǎn)生嵌套作用域。值得注意的是,一個(gè)函數(shù)作用域只有可能存在于一個(gè)父級(jí)作用域中,不會(huì)同時(shí)存在兩個(gè)父級(jí)作用域。
過(guò)程
語(yǔ)句console.log尋找變量a,b,c 其中c在自己的作用域中找到,a,b在自己的作用域中找不到,于是向上級(jí)作用域中查找,在foo的作用域中找到,并且調(diào)用。作用域向上查找的過(guò)程中,匹配第一次查找到的變量,也就是說(shuō)如果foo的作用域中也定義了c,但bar函數(shù)只調(diào)用自己作用域里的c。
作用域的查找一直會(huì)找到全局作用域的全局對(duì)象,比如瀏覽器中的window,你可以定義window.a來(lái)確保變量a可以被獲取。
詞法作用域向上查找只查找第一級(jí)變量,比如變量foo.bar.baz, 查找的是對(duì)象foo,查找到了再?gòu)膶?duì)象里獲取bar以及baz,查找本身與bar,baz無(wú)關(guān)。
動(dòng)態(tài)作用域 Dynamic Scope
動(dòng)態(tài)作用域,javascript并無(wú)采用,但是與js的 this機(jī)制非常相似,看如下代碼:
動(dòng)態(tài)作用域是在代碼運(yùn)行時(shí)定義的,而非代碼解析時(shí)。
function foo() {
console.log( a );
}
function bar() {
var a = 3;
foo();
}
var a = 2;
bar();bar調(diào)用,bar里面foo被調(diào)用,foo函數(shù)需要查找變量a,由于javascript采用詞法作用域,foo被解析的時(shí)候是在全局作用域,所以a是全局作用域中的2,而非bar里面的a。假設(shè)js采用的是動(dòng)態(tài)作用域,foo是在bar中被調(diào)用的,所以a查找到了bar作用域里的3。
作為對(duì)照,動(dòng)態(tài)作用域不關(guān)心它本身是怎樣在哪里聲明的,只關(guān)心它在哪里調(diào)用的,動(dòng)態(tài)作用域的域鏈基于調(diào)用棧,而不是代碼中的嵌套關(guān)系。
相反,詞法作用域關(guān)心的是函數(shù)在哪里聲明的,動(dòng)態(tài)作用域的概念和js中的this相同,this也關(guān)心函數(shù)在哪里調(diào)用的。
以上就是JS 詞法作用域及兩種常見(jiàn)的模型詳解的詳細(xì)內(nèi)容,更多關(guān)于JS 詞法作用域模型的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
JS代理對(duì)象Proxy初體驗(yàn)簡(jiǎn)單的數(shù)據(jù)驅(qū)動(dòng)視圖
這篇文章主要為大家介紹了JS代理對(duì)象Proxy初體驗(yàn)簡(jiǎn)單的數(shù)據(jù)驅(qū)動(dòng)視圖,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-08-08
JS前端面試數(shù)組扁平化手寫(xiě)flat函數(shù)示例
這篇文章主要為大家介紹了JS前端面試數(shù)組扁平化手寫(xiě)flat函數(shù)示例,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
微信小程序 本地存儲(chǔ)及登錄頁(yè)面處理實(shí)例詳解
這篇文章主要介紹了微信小程序 本地存儲(chǔ)實(shí)例詳解的相關(guān)資料,需要的朋友可以參考下2017-01-01
JS前端使用Canvas快速實(shí)現(xiàn)手勢(shì)解鎖特效
這篇文章主要為大家介紹了JS前端使用Canvas快速實(shí)現(xiàn)手勢(shì)解鎖特效,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-09-09
Astro Islands靜態(tài)頁(yè)面交互式UI組件
這篇文章主要為大家介紹了Astro Islands靜態(tài)頁(yè)面交互式UI組件使用示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08
apply?call?bind方法原理及使用場(chǎng)景示例詳解
這篇文章主要為大家介紹了apply&call&bind方法原理及使用場(chǎng)景示例詳解,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2023-08-08

