javascript之with的使用(阿里云、淘寶使用代碼分析)
記得還在懵懂學(xué)習(xí)JavaScript基礎(chǔ)之時(shí),坊間便有傳言“with語(yǔ)句是低效率語(yǔ)句,若非必要,請(qǐng)不要使用該語(yǔ)句”,同時(shí), ECMAScript 5 的strict mode下是禁止使用with語(yǔ)句的,所以一直以來(lái)我對(duì)with語(yǔ)句一直沒(méi)啥好感。
今天在知乎有個(gè)話題大概說(shuō)的是“你覺得什么東西相當(dāng)有B格”之類的,然后就有人貼了這段代碼:
with(document)with(body)with(insertBefore(createElement("script"), firstChild))setAttribute("exparams","category=&userid=68497352&aplus&yunid=", id = "tb-beacon-aplus", src = (location > "https" ? "http://s": "http://a") + ".tbcdn.cn/s/aplus_v2.js")
代碼拆解:
with(document)
with(body)
with(insertBefore(createElement("script"), firstChild))
setAttribute("exparams","category=&userid=68497352&aplus&yunid=",
id = "tb-beacon-aplus",
src = (location > "https" ? "http://s": "http://a") + ".tbcdn.cn/s/aplus_v2.js"
)
再拆開
var script = document.createElement("script");
document.body.insertBefore(script, document.body.firstChild);
script.setAttribute("exparams","category=&userid=68497352&aplus&yunid=",
script.id = "tb-beacon-aplus",
script.src = (location > "https" ? "http://s": "http://a") + ".tbcdn.cn/s/aplus_v2.js"
);
因?yàn)樵?JavaScript 里,可以給函數(shù)多傳一些無(wú)用參數(shù)的。
因此,最后這句話完全可以理解為:
script.id = "tb-beacon-aplus";
script.src = (location > "https" ? "http://s": "http://a") + ".tbcdn.cn/s/aplus_v2.js";
script.setAttribute("exparams","category=&userid=68497352&aplus&yunid=");
如果賦值的不是標(biāo)準(zhǔn)屬性,就不會(huì)寫出到標(biāo)簽的 attribute 里了,所以分開賦值能讓加載的外部腳本讀取到這里的附加參數(shù)。
據(jù)說(shuō)是淘寶首頁(yè)的,好奇心使然,果斷跑去淘寶看了下,有圖有真相哪:

淘寶這種大項(xiàng)目一般是十分講究效率的,居然會(huì)使用傳說(shuō)中的低效率代碼?
我們?cè)囍谜4a來(lái)達(dá)到上面的功能:
var s = document.createElement("script");
s.setAttribute("exparams","category=&userid=68497352&aplus&yunid=");
s.setAttribute("src",(location>"https"?"http://s":"http://a")+".tbcdn.cn/s/aplus_v2.js");
s.id="tb-beacon-aplus";
document.body.insertBefore(s,document.body.firstChild)
這是我能寫出的最簡(jiǎn)單的代碼了,當(dāng)然,您可以嘗試像淘寶那代碼一樣setAttribute,不過(guò)結(jié)果會(huì)讓你很受傷?。?!經(jīng)過(guò)我的測(cè)試,他那樣帶3個(gè)以上的參數(shù)設(shè)置節(jié)點(diǎn)屬性僅在with語(yǔ)句下有效,而且第三個(gè)及以后參數(shù)所設(shè)置的屬性只能是HTML標(biāo)準(zhǔn)屬性。原因我也不知道,有大牛愿意指教么?
代碼壓縮后,淘寶代碼224字節(jié),我寫的代碼264字節(jié)。
我得出的結(jié)論是:大的網(wǎng)站惜字節(jié)如金,特別是像淘寶這種每天流量巨大的網(wǎng)站,為了節(jié)省流量(別看只有幾個(gè)字節(jié),乘以個(gè)大的訪問(wèn)量后結(jié)果還是挺驚人的)而稍微犧牲下用戶代碼運(yùn)行的效率是完全值得的。況且,在瀏覽器代碼執(zhí)行效率日新月異的今天,with語(yǔ)句效率真有那么低么?
秉承一顆探索的心(此刻內(nèi)心略為激動(dòng)。。),做了如下代碼測(cè)試,
html代碼:
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>test</title> </head> <body> <div id="one" data="test data"></div> </body> </html>
with語(yǔ)句獲取div#data值
var now = +new Date;
for(var i=0;i<1000000;i++){
with(document)with(getElementById("one"))getAttribute("data")
}
console.log(new Date-now)
一般代碼獲取div#one的data值
var now = +new Date;
for(var i=0;i<1000000;i++){
document.getElementById("one").getAttribute("data")
}
console.log(new Date-now)
獲取屬性值的代碼均循環(huán)運(yùn)行100W次,輸出運(yùn)行時(shí)間,測(cè)試瀏覽器為Chrome 35與IE 11:
申明:誰(shuí)特么說(shuō)我是IE黑,我和誰(shuí)急!??!
| Chrome 35 | 數(shù)值單位:ms | ||||||||||||
| 第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 第6次 | 第7次 | 第8次 | 第9次 | 第10次 | 平均值 | 10W次差值 | 單次差值 | |
| 一般代碼 | 1362 | 1358 | 1379 | 1377 | 1372 | 1411 | 1371 | 1341 | 1356 | 1339 | 1366.6 | 888.7 | 0.89μs |
| IE 11 | 單位:ms | ||||||||||||
| 第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 第6次 | 第7次 | 第8次 | 第9次 | 第10次 | 平均值 | 10W次差值 | 單次差值 | |
| 正常情況 | 2352 | 2332 | 2321 | 2347 | 2342 | 2339 | 2365 | 2373 | 2353 | 2343 | 2346.7 | 861.7 | 0.86μs |
由于其它軟件運(yùn)行的影響及兩種代碼運(yùn)行的先后順序,結(jié)果可能不是十分嚴(yán)謹(jǐn),但個(gè)人認(rèn)為還是不會(huì)影響我們得出最終的結(jié)論:with語(yǔ)句在不是嵌套十分復(fù)雜的情況下,相比于一般代碼對(duì)執(zhí)行效率的影響其實(shí)微乎其微。
我想ECMAScript 5 的strict mode下禁用with語(yǔ)句的主要原因應(yīng)該是with語(yǔ)句讓個(gè)對(duì)象與方法與屬性的關(guān)系變得更模糊, 不利于JavaScript向面向?qū)ο缶幊炭繑n吧。
腳本之家小編補(bǔ)充:雖然有B格但不論是易于閱讀還是考慮性能的目的,很多網(wǎng)站還是使用普通的方式加載。
相關(guān)文章
使用nestjs實(shí)現(xiàn)郵件發(fā)送的代碼詳解
郵箱發(fā)送是我們常見的一個(gè)服務(wù),本篇文章帶大家用nestjs來(lái)實(shí)現(xiàn)一下,文中有詳細(xì)的代碼示例和圖文講解,對(duì)大家的學(xué)習(xí)或工作有一定的幫助,需要的朋友可以參考下2023-10-10
JavaScript encodeURI 和encodeURIComponent
encodeURI和encodeURIComponet函數(shù)都是javascript中用來(lái)對(duì)URI進(jìn)行編碼,將相關(guān)參數(shù)轉(zhuǎn)換成UTF-8編碼格式的數(shù)據(jù)。URI在進(jìn)行定位跳轉(zhuǎn)時(shí),參數(shù)里面的中文、日文等非ASCII編碼都會(huì)進(jìn)行編碼轉(zhuǎn)換2015-12-12
JavaScript的new date等日期函數(shù)在safari中遇到的坑
safari中對(duì)于JavaScript的new Date函數(shù)的支持有一個(gè)比較奇怪的問(wèn)題,帶著這個(gè)奇怪的問(wèn)題我們通過(guò)本文一起學(xué)習(xí)吧2016-10-10
Bootstrap實(shí)現(xiàn)可折疊分組側(cè)邊導(dǎo)航菜單
這篇文章主要介紹了Bootstrap實(shí)現(xiàn)可折疊分組側(cè)邊導(dǎo)航菜單的相關(guān)資料,需要的朋友可以參考下2018-03-03

