作用域

這所房子給人的感覺,就是它似乎已經沉入了無盡的睡夢,那氣氛壓制著你,不讓你醒過來,把你拖進被單下面,像喝醉了酒一樣,你沒有方法抗拒。 ——《忽然七日》

1.JavaScript的編譯過程

  • 分詞/詞法分析,產生詞法單元token
  • 解析/語法分析,生成抽象語法樹AST
  • 代碼生成,將AST轉換為可執行的代碼

第一點需要介紹的是:作用域和this環境對象完全是兩碼事。關于JavaScript的編譯及運行過程,應該了解下面這幾個名詞:作用域,引擎,編譯器。對于JavaScript來說,大部分情況下編譯發生在代碼執行前的幾微秒的時間內。舉個例子:對于var a = 2;這樣的語句在引擎和編譯器中是怎樣被處理的?常見的錯誤答案是:編譯器為一個變量分配內存,將其命名為a,然后將值保存進這個變量——這個答案并不徹底的正確,更加體現出細節的答案應該是下面這樣的:

  • 1.對于var a,編譯器會詢問作用域是否已經存在一個該名稱的變量在當前作用域的集合中。如果存在的話,編譯器會忽略掉該聲明,繼續下一步的編譯工作;如果不存在的話,那么編譯器會要求作用域在當前作用域中創建該變量,并且將其命名為a。
  • 2.接下來編譯器會為引擎創建生成運行時所需要的代碼,這些代碼被用來處理a=2這個賦值操作。引擎運行這些代碼的時候,首先會詢問當前作用域在當前作用域中是否存在a這個變量,如果存在的話,那么引擎則使用那個變量進行賦值操作,如果不存在的話,那么引擎進一步向作用域詢問在當前作用域的上一級作用域是否存在變量a,如果有,則使用,如果沒有則繼續向上一級作用域查找。查詢的終點直到查詢到了全局作用域為止,如果在全局作用域中有這個變量的話,那么引擎將會使用它。如果沒有的話,那么將會拋出一個錯誤:ReferenceError。在這里在拓展一下關于這兩個常見錯誤的知識:ReferenceError和TypeError,前者是當在查詢變量的時候查的直到了全局作用域都查不到便會拋出ReferenceError錯誤;后者是這樣的情況:查詢到了變量,但是對這個查詢到的變量進行了不合法的操作,比如說對null和undefined進行屬性引用,或者對一個非函數類型變量進行函數調用。

關于引擎查找變量也是具有兩種類型的:RHS查詢和LHS查詢,就行為上來說:前者是讀,而后者是寫。

2.作用域嵌套
在JavaScript中,我們聽到的很多一句話那就是它沒有塊作用域,只有函數作用域。不過實際上,在JavaScript語言中還是具有一些殺馬特式的塊作用域的,比如with塊作用域,ccatch塊作用域,let為變量綁定的塊作用域,const為常量綁定的塊作用域。盡管JavaScript在設計之初,并沒有加入塊作用域這個實用的東西,但是不可否認的是,他的確存在,殺馬特一般的存在著。 作用域嵌套在實際編程中是一件很常見的事情,經常一個函數的聲明會在另一個函數的聲明里面。那么問題來了,當發生作用域嵌套的時候,變量查詢規則是怎樣的呢?答案就是:由內層進行查找,內層查不到的話轉戰外層,直到全局作用域為止,一查到便停止查找,查不到就拋出ReferenceError。

3.RHS查詢和LHS查詢的某些需要注意的地方
當使用RHS查詢的時候,如果一個變量直到查找到全局作用域都查找不到的話,那么便會拋出ReferenceError,但是對于LHS查詢而言,如果查到全局作用域都查找不到的話,那么就會在全局作用域中創建這個變量(僅限于非嚴格模式,嚴格模式下一樣拋出ReferenceError)。

4.作用域的工作模型
作用域的工作模型常見的有兩種,他們分別為詞法作用域和動態作用域。關于動態作用域工作模型,目前只有較少的語言使用它;而對于詞法作用域工作模式,他被大部分語言所所支持,正如我們的JavaScript一樣。

END

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

推薦閱讀更多精彩內容

  • 官方中文版原文鏈接 感謝社區中各位的大力支持,譯者再次奉上一點點福利:阿里云產品券,享受所有官網優惠,并抽取幸運大...
    HetfieldJoe閱讀 3,251評論 5 34
  • 特別說明,為便于查閱,文章轉自https://github.com/getify/You-Dont-Know-JS...
    殺破狼real閱讀 590評論 0 0
  • 程序需要存儲變量中的值,并且能在之后對這個值進行訪問或修改。這些變量存儲在哪里?程序如何找到他們?這些問題需要一套...
    zyanfly閱讀 279評論 0 1
  • 如果我的文章對你有用,請給我一個贊,讓我有繼續堅持的動力/微笑。原創文章,此文章僅供學習參考使用,歡迎訪問我的個人...
    我就是z閱讀 499評論 0 3
  • 離三月底復試結束已經一個多月了,期間一直在忙著工作的事,現在終于可以歇口氣,順便寫寫這一路走過來的歷程,算是紀念一...
    淇水采芹人閱讀 337評論 4 1