JavaScript是解釋型語(yǔ)言她按,也就是說(shuō)渠旁,我們的js代碼會(huì)通過(guò)一個(gè)解釋器來(lái)進(jìn)行解釋執(zhí)行风响,這個(gè)解釋器我們稱(chēng)為js引擎嗜浮,因?yàn)槲覀兊臑g覽器也能執(zhí)行js羡亩,所以瀏覽器里面也有js引擎,不同的瀏覽器有不同的js引擎危融,比如chrome的V8畏铆,safari的webkit,IE瀏覽器的Trident等吉殃。
js引擎的執(zhí)行需要走三個(gè)步驟辞居,第一是進(jìn)行語(yǔ)法分析,這個(gè)比較簡(jiǎn)單蛋勺,就是看你的代碼格式是不是正確的瓦灶,比如,如果你少了個(gè)大括號(hào)抱完,就會(huì)被報(bào)錯(cuò)贼陶。
第二步是進(jìn)行預(yù)編譯,預(yù)編譯會(huì)把代碼當(dāng)中使用的變量巧娱,定義的函數(shù)解析出來(lái)碉怔,確定出環(huán)境中的變量和函數(shù)等信息,也就是這個(gè)過(guò)程會(huì)導(dǎo)致js變量提升的問(wèn)題,比如:
var a = 1; // 變量聲明
function b(y) { // 函數(shù)聲明
var x = 1;
console.log('so easy');
};
var c = function() { // 是變量聲明而不是函數(shù)聲明Q菅怠疏旨!
// ...
}
b(100);
當(dāng)js引擎進(jìn)行預(yù)編譯的時(shí)候,首選會(huì)生成一個(gè)GO(Global Object趴樱,這里是window):
GO/window = {
//頁(yè)面加載創(chuàng)建GO同時(shí),創(chuàng)建了document酪捡、navigator叁征、screen等等屬性
a: undefined,
c: undefined,
b: function(y){
var x = 1;
console.log('so easy');
}
}
第三步就是解釋并執(zhí)行代碼逛薇,直到遇到b(100)
捺疼,代碼執(zhí)行后活動(dòng)對(duì)象變成了:
GO/window = {
//頁(yè)面加載創(chuàng)建GO同時(shí),創(chuàng)建了document永罚、navigator啤呼、screen等等屬性
a: 1,
c: function() {
// ...
}卧秘,
b: function(y){
var x = 1;
console.log('so easy');
}
}
當(dāng)執(zhí)行b(100)
的時(shí)候,js引擎會(huì)針對(duì)b函數(shù)進(jìn)行預(yù)編譯官扣,創(chuàng)建AO(Active Object)對(duì)象:
AO = {
//創(chuàng)建AO同時(shí)翅敌,創(chuàng)建了arguments等等屬性,此處省略
y: 100,
x: undefined
}
然后執(zhí)行b(100)
惕蹄。
之后會(huì)一直重復(fù)進(jìn)行預(yù)編譯=>代碼執(zhí)行的過(guò)程蚯涮。