執行環境(環境)
執行環境的用處
執行環境定義了變量或函數有權訪問的其他數據,每一個執行環境都存在一個關聯的變量對象(VO),代碼無法訪問,內部解析器會使用它,如果環境為函數,則將函數的AO作為VO,函數執行時,會創建一個以當前函數VO為前端的作用域鏈,以保證執行環境有權訪問的所有變量和函數的有序訪問。
頂級AO對象 全局
全局對象(Global object) 是在進入任何執行上下文之前就已經創建了的對象;這個對象只存在一份,它的屬性在程序中任何地方都可以訪問,全局對象的生命周期終止於程序退出那一刻。
全局對象初始化
全局對象初始創建階段將Math、String、Date、parseInt作為自身屬性,等屬性初始化,同樣也可以有額外創建的其它對象作為屬性(其可以指向到全局對象自身)。例如,在DOM中,全局對象的window屬性就可以引用全局對象自身(當然,並不是所有的具體實現都是這樣)
global = {
Math: <...>,
String: <...>
...
...
window: global //引用自身
};
證據
Chrome
打印global對象時,顯示了Window類型對象,里面有一個屬性叫window就是global本身
可以看到global和global.window是指向同一對象
全局對象訪問
// 相當於 global.String(10)
String(10);
// 相當於 global.window.a = 10 === global.a = 10
window.a = 10;
// 相當於 // global.b = 20;
this.b = 20;
函數的VO對象AO
函數AO對象生成過程
函數執行前
1.分析參數
1.1 函數接收參數,添加到AO的屬性上面,值被初始化為undefined
1.2 接收實參,形成AO對應的屬性值
2.分析變量聲明,如 var a,
2.1:如果AO上還沒有a屬性鍵名,則添加a屬性鍵名並且初始化為undefined
2.2:如果AO 上面已經有了a屬性,則不做任何操作
3.分析函數的聲明,如果 funcion a(){},
3.1:無論是否該函數名存在,都會覆蓋當前函數名對應的屬性
函數執行時
4.對已經存在的變量聲明進行賦值操作
實例
function test(a, b) {
var c = 10;
function d() {}
var e = function _e() {};
(function x() {});
}
test(10); // call
1.分析參數
1.1 函數接收參數,添加到AO的屬性上面,值被初始化為undefined
AO(test) = {
a: undefined,
b: undefined
}
1.2 接收實參,形成AO對應的屬性值
AO(test) = {
a: 10,
b: undefined
}
2.分析變量聲明,如 var a,
2.1:如果AO上還沒有a屬性鍵名,則添加a屬性鍵名並且初始化為undefined
AO(test) = {
a: 10,
b: undefined,
c: undefined,
e: undefined
}
2.2:如果AO 上面已經有了a屬性,則不做任何操作
3.分析函數的聲明,如果 funcion a(){},
3.1:無論是否該函數名存在,都會覆蓋當前函數名對應的屬性
AO(test) = {
a: 10,
b: undefined,
c: undefined,
d: <reference to FunctionDeclaration "d">,
e: undefined
}
函數執行時
4.對已經存在的變量聲明進行賦值操作
AO(test) = {
a: 10,
b: undefined,
c: 10,
d: <reference to FunctionDeclaration "d">,
e: <reference to FunctionExpression "_e">
}