原文參考http://mp.weixin.qq.com/s/LijjPErxcFB4pN_wUo2cnw 調用函數時,會創建一個新的執行上下文 它的生命周期有兩個階段1創建階段-創建變數對象,建立作用域鏈,確定this的指向2執行階段-執行代碼,完成變數賦值,函數引用及其他代碼的執行 變數對象的創建 ...
原文參考http://mp.weixin.qq.com/s/LijjPErxcFB4pN_wUo2cnw
調用函數時,會創建一個新的執行上下文
它的生命周期有兩個階段
1創建階段-創建變數對象,建立作用域鏈,確定this的指向
2執行階段-執行代碼,完成變數賦值,函數引用及其他代碼的執行
變數對象的創建
1.建立arguments對象。檢查上下文中的參數,建立屬性與屬性值
2.檢查函數聲明,即用function聲明的函數。在變數對象中,key為函數名,value為指向該函數所在記憶體地址引用
3.檢查變數聲明,在變數對象中設置key為變數名,value為undefined,如果存在跳過,原屬性值不變
未進入執行階段,變數對象中各屬性無法訪問
在進入執行階段,各屬性可以訪問
變數對象和活動對象
都是同一個對象,處於不同生命周期,前者時創建階段後者是執行階段
demo1
function test(){
console.log(a)
console.log(foo())
var a = 1
function foo(){
return 2
}
}
test()
代碼執行順序為
function test(){
function foo(){
return 2
}
var a
console.log(a)
console.log(foo())
a=1
}
test()// 調用函數,即將開始創建階段
demo2
function test(){
console.log(foo)
console.log(bar)
var foo = 'Hello'
console.log(foo)
var bar = function(){
return 'world'
}
function foo(){
return 'hello'
}
}
test()
代碼執行順序
function test(){
// 執行階段先是函數引用
function foo(){
return 'hello'
}
// 變數聲明
var foo // var foo = undefined
var bar
console.log(foo) // 此時foo還是function foo(){return 'hello'},因為上面foo=undefined會跳過
console.log(bar) // undefined
foo='Hello'
console.log(foo) // hello,註意此時console在賦值之後才執行,所以能取到值
bar=function(){
return 'world'
}
}
test()
在全局上下文中變數對象就是window對象,this也是指向window
瀏覽器不關掉視窗,全局上下文一直存在