1. 程式人生 > 其它 >2020/12/18 作用域與作用域鏈

2020/12/18 作用域與作用域鏈

技術標籤:作用域及作用域鏈javascript

作用域:
1:作用域是指程式程式碼定義變數得區域。
2:作用域規定如何查詢變數,也就確定當前執行程式碼對變數得訪問許可權,或者說,當前執行程式碼使用變數賦值
3:js 中採用得靜態作用域。靜態作用域 與執行環境無關與宣告有關

作用域得分類: 全域性和區域性
1:全域性相當於瀏覽器,window 物件下所用內容都是全域性得,訪問許可權 再任意程式碼中
2:區域性作用域:函式方法體內部宣告變數,訪問許可權再方法體內部

var value = 1;
function foo() {
    console.log(value);
}
function
bar() { var value = 2; foo(); } bar(); // 結果是 ???

分析執行過程
一:靜態作用域 :執行 foo函式,先從foo函式內部查詢是否有區域性變數 value 如果沒有就根據書寫得位置,查詢上面一層得程式碼 也就是 value 等於1 所以結果會列印1。

二:動態作用域:執行 foo 函式,依然是從 foo 函式內部查詢是否有區域性變數 value。如果沒有,就從呼叫函式的作用域,也就是 bar 函式內部查詢 value 變數,所以結果會列印 2。

作用域鏈:
當查詢變數得時候,會先從當前上下文得變數物件中查詢,如果沒有就從父級執行上下文得變數物件中查詢,一直找到全域性上下文得變數物件,也就是全域性物件, 這樣由多個執行上下文得變數物件構成得連結串列結構 叫做作用域鏈

函式建立
當函式建立得時候,就會儲存所有父變數物件到[[scope]]中,你可以理解[[scope·]] 就是父變數得層級鏈 但是[[scope]] 不代表完整得作用域鏈

例子:

function foo() {
    function bar() {
        ...
    }

建立函式時:各自得[[scope]] 為:

foo.[[scope]] = [
  globalContext.VO
];

bar.[[scope]] = [
    fooContext.AO,
    globalContext.VO
];

函式啟用:
當函式啟用時,進入函式上下文,建立VO/AO後,就會將活動物件新增到作用域鏈得前端。

這時候執行上下文得作用域鏈,我們命名為 scope;

Scope = [AO].concat([[Scope]]);

現在,作用域建立完畢