一、js的運(yùn)行三部曲
1,語(yǔ)法分析:簡(jiǎn)單來(lái)說(shuō)就是通篇掃描一遍,看看有沒(méi)有語(yǔ)法錯(cuò)誤;
2,預(yù)編譯:預(yù)編譯發(fā)生再執(zhí)行的前一刻,會(huì)做兩件事情,(1)函數(shù)聲明整體提升(2)變量 聲明提升
3,解釋執(zhí)行:js有兩個(gè)特性,單線(xiàn)程和解釋性語(yǔ)言,啥叫解釋性語(yǔ)言,簡(jiǎn)單來(lái)說(shuō)就是解釋一句執(zhí)行一句
二、預(yù)編譯
1,imply global 暗示全局變量:即任何變量,如果沒(méi)有經(jīng)過(guò)聲明就賦值,此變量就為全局所有
function test(){
c = 123;//c未經(jīng)聲明就賦值,此時(shí)c就為全局變量,可以通過(guò)window.c訪(fǎng)問(wèn)到
var a = b = 123;//先將123賦值給b,發(fā)現(xiàn)b沒(méi)有聲明,此時(shí)b就為全局變量,可以通過(guò)window.b訪(fǎng)問(wèn)到
}
console.log(c);//123
console.log(b);//123
2,一切申明的全局變量全是window的屬性
var a = 123; ===> window.a = 123;
console.log(a);//123
console.log(window.a);//123
函數(shù)預(yù)編譯四部曲:
1,創(chuàng)建AO (Activation Object)對(duì)象,就是執(zhí)行期上下文
2,找形參和變量聲明,將變量和刑參作為AO對(duì)象的屬性,值為undefined
3,將實(shí)參值和刑參的值統(tǒng)一
4,在函數(shù)體里面找函數(shù)聲明,將函數(shù)名作為AO對(duì)象的屬性值掛起來(lái),值賦予函數(shù)體
全局預(yù)編譯:
1,創(chuàng)建GO (Global Object === window)對(duì)象,就是執(zhí)行期上下文
2,找變量聲明,將變量作為AO對(duì)象的屬性,值為undefined
3,在函數(shù)體里面找函數(shù)聲明,將函數(shù)名作為AO對(duì)象的屬性值掛起來(lái),值賦予函數(shù)體
function test(a){
console.log(a);
var a = 123;
console.log(a);
function a () {}
console.log(a);
var b = function () {}
console.log(b);
function d (){}
}
test();
//首先創(chuàng)建AO 對(duì)象 AO{}
// 然后找刑參和變量聲明,將變量和刑參作為AO對(duì)象的屬性,值為undefined
// AO {
// a:undefined,
// b:undefined,
// }
//再將實(shí)參和刑參的值統(tǒng)一
// AO {
// a:1,
// b:undefined
// }
//在函數(shù)體里面找函數(shù)申明,將函數(shù)名作為AO對(duì)象的屬性值掛起來(lái),值賦予函數(shù)體
// AO {
// a:function a () {}, 此時(shí)同命的a被覆蓋
// b:undefined,
// d:function d () {}
// }
//此時(shí)AO對(duì)象已經(jīng)創(chuàng)建完畢,預(yù)編譯結(jié)束,開(kāi)始執(zhí)行函數(shù)(預(yù)編譯發(fā)生在函數(shù)執(zhí)行的前一刻),AO對(duì)象就是我們所說(shuō)的作用域
//代碼執(zhí)行過(guò)程分析:
//第一行代碼開(kāi)始執(zhí)行,console.log(a);找AO對(duì)象拿值,輸出function a(){}
//第二行代碼var a = 123;開(kāi)始執(zhí)行,var a在預(yù)編譯期間已經(jīng)執(zhí)行,此時(shí)實(shí)際上相當(dāng)于執(zhí)行 a = 123;此時(shí)AO對(duì)象的a的值已經(jīng)變?yōu)?23
//第三行代碼執(zhí)行,console.log(a);找AO對(duì)象拿值,輸出123
//第四行代碼,function a(){},預(yù)編譯期間已經(jīng)執(zhí)行,跳過(guò)
//第五行代碼,console.log(a);找AO對(duì)象拿值,輸出123
//第六行代碼,執(zhí)行,AO屬性的b的值為function () {}
//第七行代碼,console.log(b);找AO對(duì)象拿值,輸出funcion (){}
//第八行代碼預(yù)編譯期間已經(jīng)執(zhí)行,跳過(guò)
//函數(shù)執(zhí)行完,AO對(duì)象變?yōu)?// AO {
// a:123, 此時(shí)同命的a被覆蓋
// b:function () {},
// d:function d () {}
// }