什么是作用域

編譯原理

傳統(tǒng)編譯語言

  • 詞法分析:將由字符組成的字符串分解成(對編譯語言來說)有意義的代碼塊,這些代碼塊被稱為詞法單元。
  • 解析/語法分析:將詞法單元流(數(shù)組)轉(zhuǎn)換成一個由元素逐級嵌套所組成的代表了程序語法結(jié)構(gòu)的樹,即“抽象語法樹”(abstract syntax tree,AST)。
  • 代碼生成:將AST轉(zhuǎn)換成可執(zhí)行代碼的過程被稱為代碼生成。這個過程與語言、目標平臺等息息相關(guān)。

相比只有三個步驟的語言的編譯器,javascript引擎要復雜的多。例如,在語法分析和代碼生成階段有特定的步驟來對運行性能進行優(yōu)化,包括對冗余元素進行優(yōu)化。簡單的說,任何javascript代碼片段在執(zhí)行前都要進行編譯(通常就在執(zhí)行前)

理解作用域

  • 程序處理過程中的角色:
    1.引擎
    從頭到尾負責整個javascript程序的編譯和執(zhí)行過程
    2.編譯器
    負責語法分析及代碼生成等臟活累活
    3.作用域
    負責收集并維護由所有聲明的標識符(變量)組成的一系列查詢,并實施一套非常嚴格的規(guī)則,確定當前執(zhí)行的代碼對這些標識符的訪問權(quán)限。
    簡單的說:作用域是一套規(guī)則,用于確定在何處以及如何查找變量(標識符)
  • 變量的賦值操作
    var a=2;
    會執(zhí)行兩個動作,首先編譯器會在當前作用域聲明一個變量(如果之前沒有聲明過),然后運行時引擎會在作用域中查找該變量,如果能夠找到就會對他賦值:

1.編譯器在編譯過程的第二步中生成了代碼,引擎執(zhí)行它時,會通過查找變量來判斷它是否以聲明過,查找的過程由作用域進行協(xié)助。

2.引擎有兩種查找類型:(1)如果查找的目的是對變量進行賦值,那么就會使用LHS查詢,(2) 如果目的是獲取變量的值,就會使用RHS查詢。這兩種查詢都會在當前執(zhí)行作用域中開始,如果他們沒有找到所需的標識符,就會向上級作用域繼續(xù)查找目標標識符,最后抵達全局作用域,這時候無論找不找的到都將停止。

3.不成功的RHS引用會導致拋出ReferenceError異常:在所有嵌套的作用域中遍尋不到所需的變量。不成功的LHS引用會導致自動隱式創(chuàng)建一個全局變量(非嚴格模式下),該變量使用LHS引用的目標作為標識符,或者拋出ReferenceError異常(嚴格模式下)

4.如果RHS查詢找到了一個變量,但你嘗試對這個變量的值進行不合理的操作,比如試圖對一個非函數(shù)類型的值進行函數(shù)調(diào)用,或者引用null或undefined類型的值中的屬性,那么引擎會拋出另外一種類型的異常,叫做TypeError。ReferenceError同作用域判別的失敗相關(guān),而TypeError則代表作用域判別成功了,但是對結(jié)果的操作是非法或不合理的

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
平臺聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點,簡書系信息發(fā)布平臺,僅提供信息存儲服務(wù)。

推薦閱讀更多精彩內(nèi)容