你不知道的javaScript上捲(第一章 作用域是什麼)

来源:http://www.cnblogs.com/wangtaoWeb/archive/2017/12/17/8052680.html
-Advertisement-
Play Games

在寫這篇博客時這本書我已經是看過一遍了,為了加深印象和深入學習於是打算做這系列的前端經典書籍導讀博文,大家如果覺得這本書講的好可以自己買來看看,我是比較喜歡看紙質版書的,因為這樣才有讀書的那種感覺。 本期我給大家講述的是 前端經典js書籍 <<你不知道的javaScript(上捲)>> 第一章內容的 ...


在寫這篇博客時這本書我已經是看過一遍了,為了加深印象和深入學習於是打算做這系列的前端經典書籍導讀博文,大家如果覺得這本書講的好可以自己買來看看,我是比較喜歡看紙質版書的,因為這樣才有讀書的那種感覺。

    本期我給大家講述的是     前端經典js書籍   <<你不知道的javaScript(上捲)>> 第一章內容的知識點總結和講解。

1.1 編譯原理

   儘管通常將js歸類為“動態”或“解釋執行”語言,但事實上它是一門編譯語言。但與傳統的編譯語言不同,他不是提前編譯的,編譯結果也不能在分散式系統中進行移植。在傳統編譯語言的流程中,程式中的一段源代碼在執行之前會經歷三個步驟,統稱為“編譯”。

        1>分詞/詞法分析

    這個過程會將由字元組成的字元串分解成(對編程語言來說)有意義的代碼塊,這些代碼塊被稱為詞法單元。例如,考慮程式 var a=2;這段程式通常會被分解成為下麵這些詞法單元 :   var 、a、=、2、;。空格是否會被當做詞法單元,取決於空格是否在這門語言中具有意義。

       2>解析/語法分析

這個過程是將詞法單元流(數組)轉換成一個由元素逐級嵌套所組成的代表了程式語法結構的樹。這個樹稱為“抽象語法樹”(AST)。

       3>代碼生成

將AST轉換為可執行代碼的過程被稱為代碼生成。這個過程與語言、目標平臺等息息相關。拋開具體細節,簡單的來說就是有某種方法可以將   var  a=2 ;的AST轉化為一組機器指令,用來創建一個叫做a的變數(包括分配記憶體等),並將一個值存儲在a中。

1.2理解作用域

為了進一步理解,我們需要多介紹一點編譯器的術語。在我們的例子中,引擎會為變數a進行LHS查詢。另外一個查找的類型叫做RHS查詢。我打賭你一定能猜到“L”和“R”的涵義,它們分別代表左側和右側。什麼東西的左側和右側?是一個賦值操作的左側和右側。

換句話說,當變數出現在賦值操作的左側時進行LHS查詢,出現在右側時進行RHS查詢。講得更準確一點,RHS查詢與簡單地查找某個變數的值別無二致,而LHS查詢則是試圖找到變數的容器本身,從而可以對其賦值。從這個角度來說,RHS並不是真正意義上的“賦值操作的右側”,更準確的說是“非左側”。

考慮以下代碼:

 1 console.log(a); 其中對a 的引用是一個RHS引用,因為這裡a並沒有賦予任何值。相應地,需要查找並取得a的值,這樣才能將值傳遞給console.log(...)。

相比之下,例如:

 1 a=2; 這裡對a的引用則是一個LHS引用,因為實際上我們並不關心當前的值是什麼,只是想要為=2這個值賦值操作找到一個目標。

1.3作用域嵌套

當一個塊或函數嵌套在另一個塊或函數中,就發生了作用域的嵌套。因此,在當前作用域中無法找到某個變數時,引擎就會在外層嵌套的作用域中繼續查找,直到找到該變數,或抵達最外層的作用域(也就是全局作用域為止)。

考慮以下代碼:

1 function foo(a){
2     console.log( a+b );
3 }
4 var b=2;
5 foo( 2 );  //4

對b進行的RHS引用無法在函數foo內部完成,但可以在上一級作用域(在這個例子中就是全局作用域)中完成。

把作用域鏈比喻成一個建築:第一層樓代表當前的執行作用域,也就是你所處的位置。建築的頂層代表全局作用域。LHS和RHS引用都會在當前樓層進行查找,如果沒有找到,就會乘坐電梯前往上一層樓,如果還沒找到就繼續向上,以此類推。一旦抵達頂層(全局作用域),可能找到了你所需的變數,也可能沒找到,但無論如何查找過程都將停止。

1.4異常

為什麼區分LHS和RHS是一件重要的事情? 因為在變數還沒有聲明(在任何作用域中都無法找到該變數)的情況下,這兩種查詢的行為是不一樣的。

考慮如下代碼:

1 function foo(a){
2        console.log( a+b );
3        b=a;
4 }
5 foo( 2 );

第一次對b進行RHS查詢時是無法找到該變數的。也就是說,這是一個“未聲明”的變數,因為在任何相關的作用域中都無法找到它。

如果RHS查詢在所有嵌套的作用域中遍尋不到所需的變數,引擎就會拋出  ReferenceError異常。相較之下,當引擎執行LHS查詢時,如果在頂層(全局作用域)中也無法找到目標變數,全局作用域中就會創建一個具有該名稱的變數,並將其返還給引擎,前提是程式運行在非嚴格模式下。

嚴格模式下在行為上有很多不同。其中一個行為就是禁止自動或隱式地創建全局變數。因此,在嚴格模式下LHS查詢失敗時,並不會創建並返回一個全局變數,引擎會拋出同RHS查詢失敗時類似的 ReferenceError異常。

 

小結:作用域是一套規則,用於確定在何處以及如何查找變數(標識符)。如果查找的目的是對變數進行賦值,那麼就會使用  LHS查詢;如果目的是獲取變數的值,就會使用    RHS查詢。賦值操作符會導致  LHS查詢。=操作符或調用函數時傳入參數的操作都會導致關聯作用域的賦值操作。js引擎首先會在代碼執行前對其進行編譯,在這個過程中,像  var  a=2 ;這樣的聲明會被分解成兩個獨立的步驟:

1.首先,var   a  在其作用域中聲明新變數。這會在最開始的階段,也就是代碼執行前進行。

2.接下來,a=2   會查詢(LHS查詢) 變數a並對其進行賦值。

LHS和RHS查詢都會在當前執行作用域開始,如果有需要(也就是說它們沒有找到所需的標識符),就會向上級作用域繼續查找目標標識符,這樣每次上升一級作用域(一層樓),最後抵達全局作用域(頂層),無論找到還是沒找到都將停止。

不成功的RHS引用會導致拋出   ReferenceError異常,不成功的LHS引用會導致自動隱式地創建一個全局變數(非嚴格模式下),該變數使用LHS引用的目標作為標識符,或者拋出  ReferenceError 異常(嚴格模式下)。

   以上就是本次的內容,如果覺得這篇博文對你有用或者讓你瞭解了一些新知識那就點波推薦吧。本人愛結交朋友,歡迎大家加我的QQ:825348114,一起進步。
            

您的分享是我們最大的動力!

-Advertisement-
Play Games
更多相關文章
  • 今天,給大家分享一個每一個程式員,或者說是碼農都會有的通病 自我懷疑。無論你的技術到達任何程度,如何任何境界,或許某一刻你的指尖會停頓,因為你的自我懷疑。 “你若想嘗試一下勇者的滋味,一定要像個真正的勇者一樣,豁出全部的力量去行動,這時你的恐懼心理將會為勇猛果敢所取代。”心理學家丘吉爾說得一句話。其 ...
  • Chimee是由奇舞團開源的一套H5視頻播放器解決方案,由奇舞團視頻雲前端團隊結合在業務和視頻編解碼方向的沉澱積累傾心打造。Chimee支持MP4、M3U8、FLV等多種媒體格式,同時它也幫我們解決了大部分的相容性、差異化問題,包括全屏、自動播放、內聯播放、直播解碼等常見媒體播放需求。 ...
  • 一、屬性相關 我們通常把特征(attribute)和屬性(property)統稱為屬性,但是他們確實是不同的概念,特征(attribute)會表現在HTML文本中,對特征的修改一定會表現在元素的outerHTML中,並且特征只存在於元素節點中;屬性(property)是對於JS對象進行修改,除了瀏覽 ...
  • 留存root javascript // Establish the root object, ( ) in the browser, // on the server, or in some virtual machines. We use // instead of for support. v ...
  • 時間:2017年12月17日 20:53:43 用於:個人總結 javascript知識點總結:1.獲取對象:document.getElementById("id")/document.getElementsTagName("li")2.事件 滑鼠事件: onclick 點擊 onmouseove ...
  • 性能分析。。。 window.performance.timing中相關屬性語義: 1.主要性能分析指標 一般指標: 實際前端更關註的指標(需要在實際中結合自身代碼): console.log('首屏圖片載入完成 : ',window.lastImgLoadTime - window.perform ...
  • 前面的話 適配器模式的作用是解決兩個軟體實體間的介面不相容的問題。使用適配器模式之後,原本由於介面不相容而不能工作的兩個軟體實體可以一起工作。適配器的別名是包裝器(wrapper),這是一個相對簡單的模式。在程式開發中有許多這樣的場景:當試圖調用模塊或者對象的某個介面時,卻發現這個介面的格式並不符合 ...
  • 最近要分析web頁面,在安卓和ios上的性能差異,除了操作系統本身不同之外,應該還多地方要探究的,第一步就是要在真機上分析。所以總結一下幾個方法。 1.Mac+iPhone+ Lightning+Safari 瀏覽器 步驟: 1)用:Lighting線將mac與iphone相連 2)iphone打開 ...
一周排行
    -Advertisement-
    Play Games
  • 移動開發(一):使用.NET MAUI開發第一個安卓APP 對於工作多年的C#程式員來說,近來想嘗試開發一款安卓APP,考慮了很久最終選擇使用.NET MAUI這個微軟官方的框架來嘗試體驗開發安卓APP,畢竟是使用Visual Studio開發工具,使用起來也比較的順手,結合微軟官方的教程進行了安卓 ...
  • 前言 QuestPDF 是一個開源 .NET 庫,用於生成 PDF 文檔。使用了C# Fluent API方式可簡化開發、減少錯誤並提高工作效率。利用它可以輕鬆生成 PDF 報告、發票、導出文件等。 項目介紹 QuestPDF 是一個革命性的開源 .NET 庫,它徹底改變了我們生成 PDF 文檔的方 ...
  • 項目地址 項目後端地址: https://github.com/ZyPLJ/ZYTteeHole 項目前端頁面地址: ZyPLJ/TreeHoleVue (github.com) https://github.com/ZyPLJ/TreeHoleVue 目前項目測試訪問地址: http://tree ...
  • 話不多說,直接開乾 一.下載 1.官方鏈接下載: https://www.microsoft.com/zh-cn/sql-server/sql-server-downloads 2.在下載目錄中找到下麵這個小的安裝包 SQL2022-SSEI-Dev.exe,運行開始下載SQL server; 二. ...
  • 前言 隨著物聯網(IoT)技術的迅猛發展,MQTT(消息隊列遙測傳輸)協議憑藉其輕量級和高效性,已成為眾多物聯網應用的首選通信標準。 MQTTnet 作為一個高性能的 .NET 開源庫,為 .NET 平臺上的 MQTT 客戶端與伺服器開發提供了強大的支持。 本文將全面介紹 MQTTnet 的核心功能 ...
  • Serilog支持多種接收器用於日誌存儲,增強器用於添加屬性,LogContext管理動態屬性,支持多種輸出格式包括純文本、JSON及ExpressionTemplate。還提供了自定義格式化選項,適用於不同需求。 ...
  • 目錄簡介獲取 HTML 文檔解析 HTML 文檔測試參考文章 簡介 動態內容網站使用 JavaScript 腳本動態檢索和渲染數據,爬取信息時需要模擬瀏覽器行為,否則獲取到的源碼基本是空的。 本文使用的爬取步驟如下: 使用 Selenium 獲取渲染後的 HTML 文檔 使用 HtmlAgility ...
  • 1.前言 什麼是熱更新 游戲或者軟體更新時,無需重新下載客戶端進行安裝,而是在應用程式啟動的情況下,在內部進行資源或者代碼更新 Unity目前常用熱更新解決方案 HybridCLR,Xlua,ILRuntime等 Unity目前常用資源管理解決方案 AssetBundles,Addressable, ...
  • 本文章主要是在C# ASP.NET Core Web API框架實現向手機發送驗證碼簡訊功能。這裡我選擇是一個互億無線簡訊驗證碼平臺,其實像阿裡雲,騰訊雲上面也可以。 首先我們先去 互億無線 https://www.ihuyi.com/api/sms.html 去註冊一個賬號 註冊完成賬號後,它會送 ...
  • 通過以下方式可以高效,並保證數據同步的可靠性 1.API設計 使用RESTful設計,確保API端點明確,並使用適當的HTTP方法(如POST用於創建,PUT用於更新)。 設計清晰的請求和響應模型,以確保客戶端能夠理解預期格式。 2.數據驗證 在伺服器端進行嚴格的數據驗證,確保接收到的數據符合預期格 ...