# 8. 编程实践
- 避免双重求值(使用eval(),Function()构造函数,setTimeout(),setInterval()),每次调用eval()时都要创建一个新的解释器/编译器实例。
- 使用Object/Array直接量,对象属性和数组项越多,使用直接量的好处就越明显。
var a={};
vara b=[];
1
2
2
- 避免重复工作
别做无关紧要的工作,别重复做已经完成的工作。
使用addEventListener和attachEvent时每次都要判断。用户不可能在页面加载完成后奇迹般的改变浏览器,那么这次检查就是重复的。如果在第一次调用addHandler()时就确定addEventListener()是存在的,那么随后每次调用时它应该也都存在。每次调用一个函数都重复相同的工作是一种浪费。
# 延迟加载
function addHandler(target,eventType,handler){
//复写现有函数
if(target.addEventListener){
addHandler=function(target,eventType,handler){
target.addEventListener(eventType,handler,false);
}
} else {
addHandler=function(target,eventType,handler){
target.attachEvent('on'+eventType,handler);
}
}
//调用新函数
addHandler(target,eventType,handler);
}
function removeHandler(target,eventType,handler){
//复写现有函数
if(target.removeEventListener){
removeHandler=function(target,eventType,handler){
target.addEventListener(eventType,handler,false);
}
} else {
removeHandler=function(target,eventType,handler){
target.detachEvent('on'+eventType,handler);
}
}
//调用新函数
removeHandler(target,eventType,handler);
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
调用延迟加载函数时,第一次总会消耗较长的时间,因为她必须运行检测接着再调用另一个函数完成任务。但随后调用相同的函数会更快,因为不需要再执行检测逻辑。当一个函数在页面中不会立刻调用时,延迟加载是最好的选择。
# 条件预加载
var addHandler=document.body.addEventListener?
function(target,eventType,handler){
target.addEventListener(eventType,handler,false);
}:
function(target,eventType,handler){
target.attachEvent('on'+eventType,handler);
}
1
2
3
4
5
6
7
2
3
4
5
6
7
条件预加载确保所有函数调用消耗的时间相同。其代价是需要在脚本加载时就检测,而不是加载后。预加载适用于一个函数马上就要被用到,并且在整个页面的生命周期中频繁出现的场合。
- 位操作过程与js其他数学运算和布尔操作相比要快很多。如果你看到32位数字的二进制底层表示,你会发现偶数的最低位是0,奇数最低位是1.当此数位偶数,那么它和1进行按位与运算的结果是0.
if(i & 1){
className="odd";//奇数
} else {
className="even";//偶数
}
1
2
3
4
5
2
3
4
5
- 原生方法 原生的querySelector()和querySelectorAll()方法完成任务平均所需时间是基于js的css查询的10%。当原生方法可用时,尽量使用它们。特别是数学运算和DOM操作。用编译后的代码做越多的事情,你的代码就越快。。Chrome对原生方法和你的代码都使用即时js编译器,所以它们之间的性能差别不大。