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