如何理解javascript代碼并提出優(yōu)化?相信有很多人都不太了解,今天小編為了讓大家更加了解,所以給大家總結(jié)了以下內(nèi)容,一起往下看吧。

作為一名前端工程師,對(duì)于javascript大家都不陌生,這篇文章從更深層次的方向——JS引擎去理解javascript到底是怎么運(yùn)行的,從而進(jìn)行優(yōu)化。

JS Engine—— JS 引擎介紹
一、基本介紹
js引擎是一個(gè)專(zhuān)門(mén)運(yùn)行javascript的解釋器(interpreter)。目前比較主流的js 引擎和介紹,大家可以簡(jiǎn)單了解一下:
V8?—? 由谷歌使用C++開(kāi)源的V8引擎,也是我們經(jīng)常聽(tīng)到的一個(gè)引擎
Rhino?—?由 Mozilla Foundation完全用Java管理的一個(gè)開(kāi)源引擎
SpiderMonkey?—?第一代js引擎,曾經(jīng)運(yùn)行在 Netscape Navigator 瀏覽器中,現(xiàn)在是Firefox
JavaScriptCore?— Safari的開(kāi)源js引擎
KJS?—?KDE 引擎,由 Harri Porten開(kāi)發(fā)
Chakra (JScript9)?—?Internet Explorer 引擎
Chakra (JavaScript)?—?Microsoft Edge 引擎
JerryScript?—輕量級(jí)的js引擎,主要用于IOT
二、V8引擎運(yùn)行流程
現(xiàn)在由于NodeJS和谷歌瀏覽器的普及,在此就主要介紹V8引擎的運(yùn)行機(jī)制,如果大家對(duì)其他引擎感興趣,可以自行查看,基本上是大同小異的

我們可以看到,JS引擎的處理過(guò)程是先解析轉(zhuǎn)換為AST語(yǔ)法樹(shù),然后由解釋器主要做兩件事,第一個(gè)是轉(zhuǎn)化為機(jī)器語(yǔ)言bytecode,第二個(gè)是交給編輯器(optimizting compiler)進(jìn)行優(yōu)化,中間還有一個(gè)數(shù)據(jù)分析過(guò)程(profilling data),主要目的是為了進(jìn)行優(yōu)化JS的運(yùn)行,優(yōu)化完畢后的代碼,再轉(zhuǎn)化為機(jī)器語(yǔ)言。
而V8引起的核心組件就分別是Ignition和TurboFan了

JS Code—— Talk is cheap
看到這,你肯定會(huì)想,我知道這有啥用,Talk is cheap,有沒(méi)有代碼可以分析的。 那么大家請(qǐng)看以下示例代碼,通過(guò)分析代碼后,我再詳細(xì)介紹其中的原理
示例代碼一:
// first case
var a = {}
var b = {}
console.time()
for (let k = 0; k < 9999999; k++) {
a[k] = 0
}
for (let i = 0; i < 9999999; i++) {
b[i] = 0
}
console.timeEnd()
// second case
var a = {}
var b = {}
console.time()
for (let k = 0; k < 9999999; k++) {
a[k] = 0
}
for (let i = 10000000; i < 19999999; i++) {
b[i] = 0
}
console.timeEnd()
// third case
var a = {}
var b = {}
console.time()
for (let k = 0; k < 9999999; k++) {
a[k] = 0
}
for (let i = 9999999; i < 0; i--) {
b[i] = 0
}
console.timeEnd()看完以上代碼,內(nèi)容很簡(jiǎn)單,就是定義object a和b 然后不斷添加屬性,唯一區(qū)別的是,first case是a和b重復(fù)添加相同的屬性,second case是a和b添加不同的屬性,third case是a和b重復(fù)添加相同的屬性,但是處理b的時(shí)候是相反順序的。
那么問(wèn)題來(lái)了:三塊代碼,運(yùn)行速度有沒(méi)有快慢之分,分別又大不大呢? (不用去確認(rèn)循環(huán)次數(shù),都是一樣滴!)
答案來(lái)了:用時(shí)時(shí)間大概是 3 (500ms)< 1 (1000ms) < 2 (2000ms),幾乎就是2倍的速度差了。
V8 Engine —— Hidden Class
我們知道,js是動(dòng)態(tài)腳本語(yǔ)言,什么意思呢,就是你可以很簡(jiǎn)單的給object添加/刪除屬性,或者改變其類(lèi)型,大部分的js解釋器(interpreter)使用字典結(jié)構(gòu),在內(nèi)存中存儲(chǔ)變量屬性值的地址,這種方式比起java和C#(非動(dòng)態(tài)語(yǔ)言,當(dāng)然了C#的dynamic類(lèi)型另當(dāng)別論,不在此贅述)要低效率的多,因?yàn)閖s的類(lèi)型是可以隨時(shí)轉(zhuǎn)換的,本來(lái)使用字典結(jié)構(gòu)結(jié)合固定的類(lèi)型進(jìn)行判斷,可以較容易的找到變量屬性值的位置,而在js中就難以實(shí)現(xiàn)了。
所以V8引擎就使用了一種高效率的方法叫Hidden Class。其他的引擎也有類(lèi)似的方法,有叫Map的, Structures的,Hidden Class的等等,在這里我們用Shape來(lái)定義它,這樣方便大家理解。
當(dāng)我們定義一個(gè)object的時(shí)候,它會(huì)包含以下內(nèi)容:


每個(gè)屬性的意義可以見(jiàn)上表。
那么結(jié)合Shape,當(dāng)定義一個(gè)object的時(shí)候,JS引擎會(huì)創(chuàng)建一個(gè)Shape (可以理解為連續(xù)的緩存buffer),它的位置0和1存儲(chǔ)了x和y值,如下圖:

如果我定義了兩個(gè)object,都是包含x和y的,那么它就會(huì)共用一個(gè)shape,如下圖:

所以到這里我們可以想象的到,我們只要定義相同屬性的object,那么都會(huì)共用一個(gè)shape,當(dāng)我們要調(diào)用任意一個(gè)shape的屬性值的時(shí)候,都可以通過(guò)同一個(gè)shape的offset來(lái)獲取到了。
那么,當(dāng)我們給object添加屬性的時(shí)候呢?V8引擎會(huì)根據(jù)類(lèi)過(guò)渡(class transition)原理創(chuàng)建新的shape來(lái)標(biāo)記位置,如下圖

也就是說(shuō),我們創(chuàng)建了3個(gè)shape,通過(guò)過(guò)渡鏈(transition chain)來(lái)實(shí)現(xiàn)一個(gè)object的追溯。
看到這里,大家肯定在想,每多一個(gè)shape肯定就會(huì)多占用一塊內(nèi)存,那么我為了優(yōu)化的話(huà),盡量在初始化的時(shí)候把屬性都定義好就能優(yōu)化了,Bingo~ 我們可以參照下圖來(lái)驗(yàn)證:

通過(guò)以上的原理解釋?zhuān)嘈糯蠹铱隙軌蛲扑憬忉尦觯覀兊氖纠a的執(zhí)行速度的區(qū)別了。
First Case:
1. Shape (empty) for a和b
2. Shape 1....9999999 for a
3. Shape 1....9999999 for b
a和b都共用了相同的shape,可以重復(fù)使用
Second Case:
1. Shape (empty) for a和b
2. Shape 1....9999999 for a
3. Shape 10000000....19999999 for b
一共定義了 1 到 19999999的shape,那么second case肯定時(shí)間要比f(wàn)irst case要花多一倍的時(shí)間了
Thrid Case:
1. Shape (empty) for a和b
2. Shape 1....9999999 for a
3. Shape 9999999 ....1 for b
以上就是如何理解javascript代碼并提出優(yōu)化的簡(jiǎn)略介紹,當(dāng)然詳細(xì)使用上面的不同還得要大家自己使用過(guò)才領(lǐng)會(huì)。如果想了解更多,歡迎關(guān)注創(chuàng)新互聯(lián)網(wǎng)站制作公司行業(yè)資訊頻道哦!
分享文章:如何理解javascript代碼并提出優(yōu)化-創(chuàng)新互聯(lián)
當(dāng)前網(wǎng)址:http://chinadenli.net/article18/edggp.html
成都網(wǎng)站建設(shè)公司_創(chuàng)新互聯(lián),為您提供關(guān)鍵詞優(yōu)化、定制開(kāi)發(fā)、微信小程序、域名注冊(cè)、網(wǎng)站策劃、移動(dòng)網(wǎng)站建設(shè)
聲明:本網(wǎng)站發(fā)布的內(nèi)容(圖片、視頻和文字)以用戶(hù)投稿、用戶(hù)轉(zhuǎn)載內(nèi)容為主,如果涉及侵權(quán)請(qǐng)盡快告知,我們將會(huì)在第一時(shí)間刪除。文章觀(guān)點(diǎn)不代表本網(wǎng)站立場(chǎng),如需處理請(qǐng)聯(lián)系客服。電話(huà):028-86922220;郵箱:631063699@qq.com。內(nèi)容未經(jīng)允許不得轉(zhuǎn)載,或轉(zhuǎn)載時(shí)需注明來(lái)源: 創(chuàng)新互聯(lián)
猜你還喜歡下面的內(nèi)容