避免全局查找
在一個函數(shù)中會用到全局對象存儲為局部變量來減少全局查找,因為訪問局部變量的速度要比訪問全局變量的速度更快些
function search() {
// 當(dāng)我要使用當(dāng)前頁面地址和主機(jī)域名
alert(window.location.href + window.location.host)
}
// 最好的方式是如下這樣 先用一個簡單變量保存起來
function search() {
var location = window.location
alert(location.href + location.host)
}
定時器
如果針對的是不斷運(yùn)行的代碼,不應(yīng)該使用 setTimeout,而應(yīng)該是用 setInterval,因為 setTimeout 每一次都會初始化一個定時器,而 setInterval 只會在開始的時候初始化一個定時器
var timeoutTimes = 0
function timeout() {
timeoutTimes++
if (timeoutTimes < 10){
setTimeout(timeout, 10)
}
}
timeout()
// 可以替換為
var intervalTimes = 0
function interval() {
intervalTimes++
if (intervalTimes >= 10){
clearInterval(interv)
}
}
var interv = setInterval(interval, 10)
字符串連接
如果要連接多個字符串,應(yīng)該少使用 +=,如
s+=a
s+=b
s+=c
應(yīng)該寫成 s+=a + b + c
二如果是收集字符串,比如多次對同一個字符串進(jìn)行+=操作的話,最好使用一個緩存,使用JavaScript 數(shù)組來收集,最后使用 join 方法連接起來
var buf = []
for (let i = 0;i < 100;i++){
buf.push(i.toString())
}
var all = buf.join("");
數(shù)字轉(zhuǎn)字符串
一般最好用 "" + 1 來將數(shù)字轉(zhuǎn)換成字符串,雖然看起來比較丑一點,但事實上這個效率是最高的,性能上來說:
(""+)>String()>.toString()>new String()
浮點數(shù)轉(zhuǎn)換成整型
很多人喜歡使用 parseInt(),其實 parseInt() 是用于將字符串轉(zhuǎn)換成數(shù)字,而不是浮點數(shù)和整型之間的轉(zhuǎn)換,我們應(yīng)該使用 Math.floor()去掉小數(shù)部分,負(fù)數(shù)減一去掉小數(shù)
或者 Math.round()四舍五入
各種類型的轉(zhuǎn)換
var myVar = "3.14159",
str = "" + myVar, // to string
i_int = ~~myVar, // to integer
f_float = 1 * myVar, // to float
b_bool = !!myVar, /* to boolean - any string with length
and any number except 0 are true */
array = [myVar]; // to array
如果定義了 toString() 方法來進(jìn)行類型轉(zhuǎn)換的話,推薦顯式調(diào)用 toString(),因為內(nèi)部的操作在嘗試所有可能性之后,會嘗試對象的 toString() 方法嘗試能否轉(zhuǎn)化為 String,所以直接調(diào)用這個方法效率會更高
多個類型聲明
在 JavaScript 中所有變量都可以使用單個 var 語句來聲明,這樣就是組合在一起的語句,以減少整個腳本的執(zhí)行時間,就如上面代碼一樣,上面代碼格式也挺規(guī)范,讓人一看就明了。
插入迭代器
如var name=values[i];i++;
前面兩條語句可以寫成var name=values[i++];
使用直接量
var aTest = new Array() // 替換為
var aTest = [];
var aTest = new Object // 替換為
var aTest = {};
var reg = new RegExp(); // 替換為
var reg = /../;
//如果要創(chuàng)建具有一些特性的一般對象,也可以使用字面量,如下:
var oFruit = new O;
oFruit.color = "red";
oFruit.name = "apple";
//前面的代碼可用對象字面量來改寫成這樣:
var oFruit = { color: "red", name: "apple" };
使用 DocumentFragment 優(yōu)化多次 append
一旦需要更新 DOM, 請考慮使用文檔碎片來構(gòu)建 DOM 結(jié)構(gòu),然后再將其添加到現(xiàn)存的文檔中。
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
document.body.appendChild(el);
}
//可以替換為:
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
使用一次 innerHTML 賦值代替構(gòu)建 dom 元素
對于大的 DOM 更改,使用 innerHTML 要比使用標(biāo)準(zhǔn)的 DOM 方法創(chuàng)建同樣的 DOM 結(jié)構(gòu)快得多。
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
//可以替換為:
var html = [];
for (var i = 0; i < 1000; i++) {
html.push('<p>' + i + '</p>');
}
document.body.innerHTML = html.join('');
通過模板元素 clone,替代 createElement
很多人喜歡在 JavaScript 中使用 document.write 來給頁面生成內(nèi)容。事實上這樣的效率較低,如果需要直接插入 HTML,可以找一個容器元素,比如指定一個 div 或者 span,并設(shè)置他們的 innerHTML 來將自己的 HTML 代碼插入到頁面中。通常我們可能會使用字符串直接寫 HTML 來創(chuàng)建節(jié)點,其實這樣做,1 無法保證代碼的有效性 2 字符串操作效率低,所以應(yīng)該是用 document.createElement() 方法,而如果文檔中存在現(xiàn)成的樣板節(jié)點,應(yīng)該是用 cloneNode() 方法,因為使用 createElement() 方法之后,你需要設(shè)置多次元素的屬性,使用 cloneNode() 則可以減少屬性的設(shè)置次數(shù)——同樣如果需要創(chuàng)建很多元素,應(yīng)該先準(zhǔn)備一個樣板節(jié)點
var frag = document.createDocumentFragment();
for (var i = 0; i < 1000; i++) {
var el = document.createElement('p');
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);
//替換為:
var frag = document.createDocumentFragment();
var pEl = document.getElementsByTagName('p')[0];
for (var i = 0; i < 1000; i++) {
var el = pEl.cloneNode(false);
el.innerHTML = i;
frag.appendChild(el);
}
document.body.appendChild(frag);