一广鳍、JavaScript概念
JavaScript ( JS ) 是一個(gè)單線程耗绿、解釋型的編程語(yǔ)言箕母。
二储藐、JavaScript語(yǔ)言特點(diǎn)
2.1 單線程
JavaScript語(yǔ)言的一大特點(diǎn)就是單線程,也就是說(shuō)嘶是,同一個(gè)時(shí)間只能做一件事钙勃。
2.2 解釋型語(yǔ)言
自上而下,解釋一行聂喇,執(zhí)行一行辖源;不會(huì)通篇編譯為一個(gè)文件再執(zhí)行。
三希太、 JavaScript執(zhí)行過(guò)程
3.1 語(yǔ)法分析
顧名思義 就是檢查一遍js代碼內(nèi)有沒(méi)有出現(xiàn)語(yǔ)法錯(cuò)誤(比如少些個(gè)分號(hào)克饶,多寫個(gè)括號(hào)等);語(yǔ)法分析期間不會(huì)執(zhí)行代碼
3.2 預(yù)編譯
預(yù)編譯發(fā)生在函數(shù)執(zhí)行的前一刻
全局下:
全局的變量聲明和函數(shù)聲明則會(huì)存放在全局對(duì)象內(nèi)(Global Object 簡(jiǎn)稱GO誊辉,它是window的一部分矾湃,你可以直接把他理解成window對(duì)象)中
函數(shù)體內(nèi):
預(yù)編譯會(huì)提前把函數(shù)里的變量聲明和函數(shù)聲明依據(jù)規(guī)則存放在該活動(dòng)對(duì)象內(nèi)(Activation Object,簡(jiǎn)稱AO)堕澄,
預(yù)編譯簡(jiǎn)單理解就是在內(nèi)存中開辟一些空間邀跃,存放一些變量與函數(shù) 。
預(yù)編譯大致可分為4步:
- 創(chuàng)建AO(GO)對(duì)象
- 找形參和變量聲明蛙紫,將形參和變量名作為AO(GO)屬性名拍屑,值為undefined
- 將實(shí)參值和形參統(tǒng)一
- 在函數(shù)體里面找函數(shù)聲明,值賦予函數(shù)體惊来。
所以如果遇到下面這種情況丽涩,當(dāng)函數(shù)聲明和變量聲明名稱相同時(shí):
console.log(a);
var a= 1;
function a(){};
編譯后的代碼其實(shí)是:
var a;
function a(){};
console.log(a);
a= 1;
所以最后輸出的是:
function a() {}
預(yù)編譯小節(jié)
預(yù)編譯兩個(gè)小規(guī)則
- 函數(shù)聲明整體提升—(具體點(diǎn)說(shuō),無(wú)論函數(shù)調(diào)用和聲明的位置是前是后裁蚁,系統(tǒng)總會(huì)把函數(shù)聲明移到調(diào)用前面)
- 變量 聲明提升—(具體點(diǎn)說(shuō)矢渊,無(wú)論變量調(diào)用和聲明的位置是前是后,系統(tǒng)總會(huì)把聲明移到調(diào)用前枉证,注意僅僅只是聲明矮男,所以值是undefined),只有在解釋執(zhí)行階段才會(huì)進(jìn)行變量初始化室谚,匿名函數(shù)不參與預(yù)編譯毡鉴。
預(yù)編譯前奏
- imply global 即任何變量崔泵,如果未經(jīng)聲明就賦值,則此變量就位全局變量所有(全局域就是window) 猪瞬。
- 一切聲明的全局變量憎瘸,全是window的屬性。
<script>
var a=2;
console.log(window.a);//2
</script>
3.3 解釋執(zhí)行
預(yù)編譯完畢之后陈瘦,JavaScript 腳本開始執(zhí)行幌甘,執(zhí)行順序按照從上到下的順序執(zhí)行。
總結(jié)
JavaScript執(zhí)行順序
- 語(yǔ)法分析
- 預(yù)編譯
2.1. 創(chuàng)建AO(GO)對(duì)象
2.2. 找形參和變量聲明痊项,將形參和變量名作為AO(GO)屬性名锅风,值為undefined
2.3. 將實(shí)參值和形參統(tǒng)一
2.4. 在函數(shù)體里面找函數(shù)聲明,值賦予函數(shù)體鞍泉。 - 解釋執(zhí)行
練習(xí):
function a(a){
console.log(a);
a= 2;
console.log(b);
var b= 3;
console.log(a);
}
a(1);
console.log(a);
你可以先試想一下結(jié)果皱埠,然后復(fù)制代碼到控制臺(tái)去驗(yàn)證你的答案是否正確。