在系列(四)中,我留下了本身的疑惑,其實我是有答案的。答案就是遵循"忽略原則"。若是不忽略整個運行機制想必會亂套。MMP瀏覽器
繼續個人變量對象筆記記錄...bash
爲了更加深入地理解變量對象,這回咱們結合一些實例來探討。微信
5.1 實例分析函數
//demo01
function test() {
console.log(a);
console.log(foo());
var a = 1;
function foo() {
return 2;
};
}
test();複製代碼
當運行test函數時,咱們說他對應的執行上下文被激活(建立)。咱們知道執行上下文的生命週期有兩個階段(建立階段和執行階段)。在這裏咱們用以下形式來表達這個過程:學習
//建立過程
testEC = {
VO: {}, //變量對象
scopeChain: [], //做用域鏈
this: {}
}
//學習js是漸進加強的過程,因此這裏對做用域鏈和this不作過多解釋,目前咱們只關注變量對象(VO)
VO = {
arguments: {...},
foo: <foo reference> //函數應用
a: undefined
}複製代碼
在call stack中,若是當前執行上下文處於call stack的棧頂,則意味着這個執行上下文出於激活狀態,此時變量對象稱之爲活動對象(AO, Activation Object)。活動對象包含變量對象的全部屬性,而且此時全部的屬性都已完成賦值(在這裏就須要注意了:變量賦值是發生在執行上下文的執行階段),除此以外,活動對象還包含了this指向。ui
//執行階段
VO -> AO
AO = {
arguments: {},
foo: <foo reference>,
a: 1,
this: window
}複製代碼
所以上面例子實際執行順序爲:this
function test() {
function foo() {
return 2;
}
var a = undefined;
console.log(a);
console.log(foo());
a = 1;
}
test();複製代碼
下面咱們再來看個例子鞏固一下:spa
//demo02.js
function test() {
consloe.log(foo);
console.log(bar);
var foo = 'Hello';
console.log(foo);
var bar = function() {
return 'world';
}
function foo() {
return 'hello'
}
}
test();複製代碼
運行test函數時,對應的上下文開始建立,能夠用以下形式來表達這個過程:code
//建立過程
testEC = {
VO: {
arguments: {},
foo: <foo reference>,
bar: undefined
}, //變量對象
scopeChain: [], //做用域鏈
this: {}
}
//執行階段
VO -> AO
AO = {
arguments: {...},
foo: 'Hello',
bar: <bar referencer>,
this: window
}複製代碼
融合整個知識點,相信您變量對象已經掌握了。對象
5.2 全局上下文的變量對象
以瀏覽器爲例,全局對象爲window對象。
全局上下文的變量對象有一個特殊的地方,即他的變量對象就是window對象,並且全局上下文的變量對象不能變成活動對象。
除此以外,全局上下文的生命週期與程序的生命週期一致,只要程序運行不結束(好比關掉瀏覽器窗口),全局上下文就會一直存在,其它全部的執行上下文都能直接訪問全局上下文的屬性(這一點很重要)。
到這裏,個人變量對象學習過程也就結束了。
記住:執行上下的生命週期、變量對象->活動對象、全局上下文的特殊性。
這些都是我以往的學習筆記。若是您看到此筆記,但願您能指出個人錯誤。有這麼一個羣,裏面的小夥伴互相監督,堅持天天輸出本身的學習心得,不輸出就出局。但願您能加入,咱們一塊兒終身學習。歡迎添加個人我的微信號:Pan1005919589