91超碰碰碰碰久久久久久综合_超碰av人澡人澡人澡人澡人掠_国产黄大片在线观看画质优化_txt小说免费全本

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

JavaScript作用域從局部到全局介紹

發布時間:2023-08-11 15:01:08 來源:億速云 閱讀:136 作者:栢白 欄目:開發技術

本篇文章和大家了解一下JavaScript作用域從局部到全局介紹。有一定的參考價值,有需要的朋友可以參考一下,希望對大家有所幫助。

JavaScript作用域深度剖析:從局部到全局一網打盡

1.1 編譯原理

  • JavaScript 事實上是一門編譯語言。

在傳統編譯語言中,一段源代碼執行前會經歷三個步驟:

分詞/詞法分析(Tokenizing/Lexing)

var a = 2;
// 分解后:
var、a、=、2、;
// 空格是否會被當做詞法單元,取決于空格在這門語言中是否具有意義。
  • 期間經過兩個過程:分詞(tokenizing)和詞法分析(Lexing) 、兩者的主要差別在于詞法單元的識別是通過有狀態還是無狀態的方式進行的。

解析/語法分析(Parsing)

  • 這個過程就是將詞法單元流(數組)轉換為一個由元素逐級嵌套組成的代表了程序語法結構的樹,這個樹被稱為"抽象語法樹"。(Abstract Syntax Tree, AST)。

代碼生成

  • 將 AST 轉換為可執行代碼的過程被稱為代碼生成。也就是說有某種方法將 var a = 2; 的 AST 轉換為一組機器指令,用來創建一個叫做 a 的變量(包含分配內存等),將一個值儲存于 a 中。

  • 比起其他編譯過程只有這三個步驟的語言的編譯器,JavaScript 引擎要復雜得多,在語法分析和代碼生成階段有著特定的步驟來對比運行性能進行優化,包括對冗余元素進行優化等。

  • 簡單來說,任何 JavaScript 代碼片段在執行前都要進行編譯(通常就在執行前)

1.2 理解作用域

1.2.1 演員表
  • 引擎:從頭到尾負責整個 JavaScript 程序的編譯及執行過程。

  • 編譯器:引擎的好朋友之一,負責語法分析及代碼生成等臟活累活。

  • 作用域:引擎的另一個好朋友,負責收集并維護由所有聲明的標識符(變量)組成的一系列查詢,并實行一套嚴格的規則,確定當前執行的代碼對這些標識符的訪問權限。

1.2.2 對話
  • var a = 2; 這段代碼是一句聲明。但會經過編譯器和引擎的處理來進行。

  • S: 變量的賦值操作會執行兩個動作,首先編譯器會在當前作用域中聲明一個變量(如果之前沒有聲明過),然后在運行時引擎會在作用域中查找該便令,如果能夠找到就會對它進行賦值。

1.2.3 編譯器有話說

編譯器在編譯過程中的第二步中生成了代碼,引擎執行它時,會通過查找變量 a 來判斷他是否已聲明過。查找的過程由作用域進行協助,但是引擎執行怎樣的查找會影響最終的查找結果。

引擎常使用的查詢類型為:LHS和RHS

LHS: 賦值操作的目標是誰

RHS: 誰是賦值操作的源頭

1.2.5
function foo(a) {
    var b = a;
    return a + b;
}
var c = foo(2);
// 對話:
1. 聲明 var c
2. 對 c 進行 LHS
3. 對 foo(2) 進行 RHS
4. function foo(a) 期間會進行 a = 2, 對 a 進行 LHS
5. 聲明 var b
6. 對 b 進行 LHS
7. 對 a 進行 RHS
8. return a + b; 分別對 a、b 進行 RHS
// 答案:
1. 所有的 LHS(一共有3處)
    1. c =..;
    2. a = 2(隱士變量分配)
    3. b = ..
2. 所有的 RHS (一共有4處)
    1. foo(2..
    2. = a;
    3. a..
    4. .. b

1.3 作用域嵌套

作用域是根據名稱查找變量的一套規則。

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

// 非嚴格模式下
function foo(a) {
console.log(a + b);
}
var a = 2;
foo(2); // 4
// 嚴格模式下:
function foo(a) {
console.log(a + b);
}
var a = 2;
foo(2); // 4

遍歷嵌套作用域鏈的規則:引擎會從當前的執行作用域中開始查找變量,如果找不到就會向上一級中繼續查找。當抵達最外層的全局作用域時,無論找到還是沒找到,查找的過程都會停止。

例子:

JavaScript作用域從局部到全局介紹

  • 整個建筑代表程序中的嵌套作用域鏈,第一層樓代表當前的執行作用域,也就是你所處的位置。建筑的頂層代表全局作用域。

  • 引擎查找的方式:LHS 和 RHS 引用會先在當前樓層中進行查找,如果沒找到,就會坐電梯前往上一層樓樓,如果還是沒找到就會繼續上下,以此類推。一旦達到了頂層(全局作用域), 可能找到你了你所需的變量,也可能沒找到,但無論如何查找過程都會停止。

1.4 異常

為什么區分 LHS 與 RHS 是一種重要的事?

因為在變量還未聲明(在任何作用域中都無法找到該變量)的情況下,引擎的這兩種查詢行為是不一樣的。

// 非嚴格模式下:
function foo(a) {
console.log(a + b);
b = a;
}
foo(2); // 4
// 嚴格模式下:
'use strict';
function foo(a) {
console.log(a + b);
b = a;
}
foo(2); // ReferenceError: b is not defined

上述代碼引擎行為:

  • 非嚴格模式下:

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

第二次對 b(b = ..) 進行 LHS 查詢時,如果在頂層(全局作用域)中也沒找到該變量,就會在全局作用域中隱式地創建一個該名稱的變量,并將其返回給引擎。

......

  • 嚴格模式下:

第一次對 b(.. + b) 進行 RHS 查詢時未找到該變量,也就是說,這是一個"未聲明" 的變量,因為在任何相關的作用域都無法找到它,直接拋出 'ReferenceError'。

......

  • 非嚴格模式下引擎查找規則

    當引擎執行 RHS 查詢在所有嵌套的作用域中找不到所需的變量,引擎就會拋出 ReferenceError 異常。

    當引擎執行 LHS 查詢時,如果在頂層作用域中也無法找到該變量,全局作用域就會創建一個該名稱的變量,并將其返回給引擎(非嚴格模式下)。

  • 嚴格模式下引擎查找規則

    ES5 引入了 "嚴格模式"(use strict),在行為上有很多不同,其中一個不同的行為就是嚴格模式下禁止自動或隱式地創建全局變量。因此在嚴格模式中引擎執行 LHS 查詢失敗時,并不會創建一個全局變量,而是直接拋出一個 ReferenceError

    如果 RHS 找到了一個變量,但嘗試對這個變量進行一些不合理的操作時,比如對一個非函數類型的值進行函數調用,或者引用 null 或 undefined 類型的之中屬性,那引擎則會拋出另外一種類型的異常 TypeError。

  • ReferenceError 同作用域判斷失敗相關,而 TypeError 代表作用域判別成功了,但對結果的操作是非法或不合理的。

1.5 小結

作用域是根據名稱查找變量的一套規則。

引擎常使用的查詢類型為:LHS 和 RHS

  • LHS: 賦值操作的目標是誰

  • = 操作符在調用函數時的形參會導致關聯作用的賦值操作。也就是說 foo (a, b, c...), 都會有 a = xxx, b = xxx, c = xxx ...... 的行為。

  • RHS: 誰是賦值操作的源頭

非嚴格模式下引擎查找規則

當引擎執行 RHS 查詢在所有嵌套的作用域中找不到所需的變量,引擎就會拋出 ReferenceError 異常。

當引擎執行 LHS 查詢時,如果在頂層作用域中也無法找到該變量,全局作用域就會創建一個該名稱的變量,并將其返回給引擎(非嚴格模式下)。

嚴格模式下引擎查找規則

ES5 引入了 "嚴格模式"(use strict),在行為上有很多不同,其中一個不同的行為就是嚴格模式下禁止自動或隱式地創建全局變量。因此在嚴格模式中引擎執行 LHS 查詢失敗時,并不會創建一個全局變量,而是直接拋出一個 ReferenceError

如果 RHS 找到了一個變量,但嘗試對這個變量進行一些不合理的操作時,比如對一個非函數類型的值進行函數調用,或者引用 null 或 undefined 類型的之中屬性,那引擎則會拋出另外一種類型的異常 TypeError。

  • ReferenceError 同作用域判斷失敗相關,而 TypeError 代表作用域判別成功了,但對結果的操作是非法或不合理的。

特殊字符描述:

  • 問題標注 Q:(question)

  • 答案標注 R:(result)

  • 注意事項標準:A:(attention matters)

  • 詳情描述標注:D:(detail info)

  • 總結標注:S:(summary)

  • 分析標注:Ana:(analysis)

  • 提示標注:T:(tips)

以上就是JavaScript作用域從局部到全局介紹的簡略介紹,當然詳細使用上面的不同還得要大家自己使用過才領會。如果想了解更多,歡迎關注億速云行業資訊頻道哦!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

普安县| 古交市| 阳江市| 南昌市| 吉首市| 平乡县| 郎溪县| 长武县| 宿松县| 名山县| 临猗县| 陆丰市| 天等县| 志丹县| 和顺县| 汪清县| 聊城市| 津市市| 原阳县| 田东县| 广昌县| 萝北县| 遵化市| 德江县| 新蔡县| 正定县| 广安市| 莱州市| 工布江达县| 聊城市| 金平| 安丘市| 无为县| 中西区| 安福县| 台北市| 临清市| 衡东县| 贞丰县| 巍山| 运城市|