js運行三部曲
1.語法分析
2.預編譯
3.解釋執行
imply global 暗示全局變量:即任何變量,如果變量未經聲明就賦值,此變量就爲全局對象GO所有
一切聲明的全局變量,全是window的屬性
預編譯發生在執行之前,且預編譯執行的地方不會在執行
函數每次執行的時候,都會產生AO,並且每次調用完之後AO對象會銷燬
函數預編譯
1.創建AO對象
2.找形參和變量聲明,將形參和變量作爲AO屬性名,值爲undefined
3.形參值和實參值相統一
4.在函數體裏面尋找函數聲明,值賦予函數體
以上的預編譯按順序執行,後面的會覆蓋前面的
全局預編譯
1.創建GO對象
2.變量作爲GO的屬性名,值賦爲undefined
3.尋找函數,值賦爲函數體
function fn(a){
console.log(a);
var a = 123;
console.log(a);
function a(){}
console.log(a);
var b = function () {}
console.log(b);
function d(){}
}
fn(1);
預編譯步驟實例
1.創建AO對象
AO{
a: undefined
b: undefined
}
3.將形參和實參值統一
AO
{
a: 1
b: undefined
}
4.在函數體裏面尋找函數聲明,值賦予函數體
AO
{
a: function a() {}
b: undefined
d: function d() {}
}
創建AO對象之後,執行函數
輸出的東西都在AO對象裏面
第一個輸出: function a () {}
AO{
a: 123 // var a = 123;
b: undefined
d: function d() {}
}
第二個輸出: 123
第三個輸出: 123
AO{
a: 123
b: function () {} // var b = function() {}
d: function d() {}
}
第四個輸出: function b() {}
全局的與此類似,只是建立的是GO對象
作用域鏈
函數的[[scope]]屬性,只有系統可以調用的屬性,
function a() {
function b() {
var b = 234;
}
var a = 123;
b();
}
var glob = 100;
a()
a的scope chain :
B在a的基礎上增加自己的AO並且在最上面構成他的作用域鏈,而每當執行的時候,從最上面開始找變量或函數,這也很好的解釋了javascript中函數內部可以用全局變量,因爲全局變量全部都在GO當中,所以不會出現報錯的情況。