4、减少作用域链上的查找次数
我们知道,js代码在执行的时候,如果需要访问一个变量或者一个函数的时候,它需要遍历当前执行环境的作用域链,而遍历是从这个作用域链的前端一级一级的向后遍历,直到全局执行环境,所以这里往往会出现一个情况,那就是如果我们需要经常访问全局环境的变量对象的时候,我们每次都必须在当前作用域链上一级一级的遍历,这显然是比较耗时的,我们看下面的例子:
<
div
id
=
"demo"
></
div
>
<
input
id
=
"but1"
type
=
"button"
onclick
=
"func1()"
value
=
"效率低"
/>
<
input
id
=
"but2"
type
=
"button"
onclick
=
"func2()"
value
=
"效率高"
/>
|
function
func1(){
var
start =
new
Date().getTime();
for
(
var
i = 0; i < 10000; i++){
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
var
but1 = document.getElementById(
"but1"
);
var
but2 = document.getElementById(
"but2"
);
var
inputs = document.getElementsByTagName(
"input"
);
var
divs = document.getElementsByTagName(
"div"
);
}
var
end =
new
Date().getTime();
alert(
"用时 "
+ (end - start) +
" 毫秒"
);
}
function
func2(){
var
start =
new
Date().getTime();
var
doc = document;
for
(
var
i = 0; i < 10000; i++){
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
var
but1 = doc.getElementById(
"but1"
);
var
but2 = doc.getElementById(
"but2"
);
var
inputs = doc.getElementsByTagName(
"input"
);
var
divs = doc.getElementsByTagName(
"div"
);
}
var
end =
new
Date().getTime();
alert(
"用时 "
+ (end - start) +
" 毫秒"
);
}
|
上面代码中,第二种情况是先把全局对象的变量放到函数里面先保存下来,然后直接访问这个变量,而第一种情况是每次都遍历作用域链,直到全局环境,我们看到第二种情况实际上只遍历了一次,而第一种情况却是每次都遍历了,所以我们看看其执行结果:
IE6.0 | ||||||
函数 | 第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 平均 |
func1 | 1627ms | 1627ms | 1642ms | 1627ms | 1626ms | 1629.8ms |
func2 | 985ms | 1002ms | 1001ms | 985ms | 985ms | 991.6ms |
Firefox4.0 | ||||||
函数 | 第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 平均 |
func1 | 72ms | 71ms | 72ms | 72ms | 82ms | 73.8ms |
func2 | 72ms | 71ms | 73ms | 83ms | 70ms | 73.8ms |
Chrome6.0 | ||||||
函数 | 第1次 | 第2次 | 第3次 | 第4次 | 第5次 | 平均 |
func1 | 62ms | 71ms | 63ms | 78ms | 78ms | 70.4ms |
func2 | 78ms | 62ms | 62ms | 71ms | 62ms | 67ms |
从上表中可以看出,其在IE6下差别还是非常明显的,而且这种差别在多级作用域链和多个全局变量的情况下还会表现的非常明显。
转载于:https://blog.51cto.com/xiaoahei/1221929