一、總原則
減少操作:js引擎弛矛,業(yè)務(wù)代碼
本文主要從變量訪問和算法邏輯討論
二跺嗽、變量訪問
數(shù)據(jù)類型
數(shù)據(jù)存放的位置不同決定了數(shù)據(jù)訪問的速度不同。JavaScript中有四種基本的數(shù)據(jù)類型:
字面量 (Literal values)
變量存儲(chǔ)的是實(shí)際數(shù)值砍聊。JavaScript字面量類型有:字符串背稼,數(shù)字,布爾值玻蝌,對象蟹肘,數(shù)組,函數(shù)俯树, 正則表達(dá)式帘腹,NULL,undefined變量 (Vriables)
用vars聲明的變量用于存儲(chǔ)數(shù)據(jù)值數(shù)據(jù)項(xiàng) (Array items)
對象成員 (Object members)
NOTES:
a. 前兩類存儲(chǔ)在棧中许饿,后兩項(xiàng)存儲(chǔ)在堆中
b. 前兩類訪問速度高于后兩種
作用域
聲明一個(gè)函數(shù)實(shí)際是創(chuàng)建一個(gè)Function類的實(shí)例
在函數(shù)創(chuàng)建時(shí)阳欲,建立一個(gè)[[Scope]]的內(nèi)部屬性,定義了該函數(shù)可訪問的數(shù)據(jù),稱為作用域鏈球化。創(chuàng)建器作用域鏈 = 全局變量:browser秽晚,window, document等
在函數(shù)運(yùn)行時(shí),建立一個(gè)‘運(yùn)行期上下文’的內(nèi)部屬性筒愚,定義了該函數(shù)運(yùn)行期間作用域鏈等執(zhí)行環(huán)境赴蝇。運(yùn)行期作用域鏈 = [[Scope]]作用域鏈 + 局部變量,參數(shù)巢掺,this句伶,參數(shù)等,按照棧的方式存儲(chǔ)
實(shí)例1: 定義以下函數(shù)
function add(num1, num2) {
const sum = num1 + num2;
return sum
}
創(chuàng)建期間的作用域鏈
執(zhí)行函數(shù)時(shí)作用域鏈
實(shí)例2: 定義以下閉包
function assignEvents() {
var id = "123"
document.getElementById('save-btn').onclick = function(event) {
saveDocument(id)
}
}
創(chuàng)建期閉包函數(shù)作用域鏈
執(zhí)行期閉包函數(shù)作用域鏈
結(jié)論:變量在作用域鏈的位置越深越慢址遇,全局最慢熄阻,局部最快
提升:用本地局部變量緩存全局變量等訪問速度慢的變量
三、優(yōu)化實(shí)例
3.1 局部變量緩存
多次訪問document的函數(shù)
function initUI(){
var bd = document.body,
links = document.getElementsByTagName_r("a"),
i = 0,
len = links.length;
while(i < len){
update(links[i++]);
}
document.getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active"
}
緩存document后
function initUI(){
var doc = document,
bd = doc.body,
links = doc.getElementsByTagName_r("a"),
i = 0,
len = links.length;
while(i < len){
update(links[i++]);
}
doc.getElementById("go-btn").onclick = function(){
start();
};
bd.className = "active";
}
3.2 字符串連接
使運(yùn)算符時(shí)倔约,盡量使用+=秃殉,-=、=浸剩、=等運(yùn)算符號(hào)钾军,而不是直接進(jìn)行賦值運(yùn)算。
實(shí)例1
如果是追加字符串绢要,最好使用s+=anotherStr
;而不是要使用s=s+anotherStr
實(shí)例2
拼接多個(gè)字符串
// bad
x+=a; x+=b; x+=c;
/// good
x+= a + b + c;
3.3 原型鏈
對象的繼承是通過原型對象實(shí)現(xiàn)的
實(shí)例1
定義如下對象
var book = {
title: "High Performance JavaScript",
publisher: 'Yahoo'
}
原型鏈為實(shí)例2
定義如下對象
function Book(title, publisher){
this.title = title;
this.publisher = publisher;
}
Book.prototype.sayTitle = function(){
alert(this.title);
};
var book1 = new Book("High Performance JavaScript", "Yahoo! Press");
alert(book1 instanceof Book); //true
alert(book1 instanceof Object); //true
book1.sayTitle(); //"High Performance JavaScript"
book1.toString(); //"[object Object]"
結(jié)論:對象成員在原型鏈上的位置越深速度越慢
提升:減少.的操作吏恭,緩存對象成員的值
四、算法與流程控制優(yōu)化
4.1 循環(huán)語句
主要進(jìn)行下面幾種優(yōu)化方案:
1 減少對象成員和數(shù)組項(xiàng)查找次數(shù)
2 減少迭代次數(shù)
3 緩存中間值
for (var i=0; i < items.length; i++){
process(items[i]);
}
上面的代碼每次循環(huán)要做的操作:
1. 讀取屬性:items.length
2. 執(zhí)行比較:i < items.length
3. 判斷條件:i < items.length === true
4. 自加操作:i++
5. 數(shù)據(jù)查找:items[i]
6. 函數(shù)調(diào)用:process(items[i])
優(yōu)化后
for (var i=0, l=items.length; i < l ; i++){
process(items[i])
}
4.2 條件判斷
主要是if-else和switch
1. 將常用的條件放在前面
if (value < 5) {
//do something
// <5為高概率事件
} else if (value > 5 && value < 10) {
//do something
// 5-10為中概率事件
} else {
//do something
}
2 查表法
適合大量離散數(shù)據(jù)的條件判斷
| |
優(yōu)化后
//define the array of results
var results = [result0, result1, result2, result3, result4]
//return the correct result
return results[value];
或使用策略模式
//define the array of resultsvar results = [result0, result1, result2, result3, result4]//return the correct result
return results[value];