作用域:在js預編譯時、代碼執行之前對全域或區域的變數進行收集,存放在一指定記憶體中scope,執行時對scope進行訪問,scope 就是全域或區域的作用域,
如:
1 function test() { 2 var a = 123; 3 } 4 5 test();
在test() 執行之前對test 進行預編譯 生成test 的 scope(AO Activetion Object),收集test 函式中的變數存放在scope中,
此時test 的scope 為:
{
a:undefined
}
在test 函式執行時 對 scope 中的 a 變數進行賦值,a = 123;
實際上在全域環境進行預編譯時也會產生一個作用域,在test 被定義時會在test 函式上定義一個作用域陣列([[Scopes]]),并將全域作用域放入test的作用域陣列中,
如:
1 var a = 456; 2 3 function test() { 4 var b = 123; 5 console.log(b); 6 console.log(a); 7 } 8 9 test();
在全域環境進行預編譯時,會生成全域作用域Global
Global {
a: undefined,
test: undefined
}
此時test 函式的作用域陣列中就已經包含了Global
test.[[Scopes]] = [Global] // 實際上[[Scopes]] 是不可訪問的
全域環境執行完后Global變成
Global{
a: 456,
test: function test() {...}
}
在test 函式執行前會對test函式進行預編譯,生成test 函式的scope并放入到test 函式的作用域陣列的第一位,
scope {
b: undefined
}
test.[[Scopes]] = [scope,Global] // 實際上[[Scopes]] 是不可訪問的
在test 代碼執行b= 123時對作用域scope 中的b進行賦值
scope {
b: 123
}
在test 函式中列印a 時會沿著test 作用域陣列中的順序進行查找,首先會查找test 的scope 中是否有a,如果有者直接使用,如果沒有沿著[[Scopes]] 繼續查找,在Global 中進行查找,所以列印的是Global 中的a的值--456,
如果沿著[[Scopes]] 的順序找到Global 一直找不到a,就會報錯 a is not defined,
由于在訪問變數時會沿著[[Scopes]] 查找,這種查找機制類似鏈條結構,所以稱[[Scopes]] 為作用域鏈,
轉載請註明出處,本文鏈接:https://www.uj5u.com/qiye/144614.html
標籤:JavaScript
下一篇:JS陣列之轉換方法
