四、减小做用域链上的查找次数
咱们知道,js代码在执行的时候,若是须要访问一个变量或者一个函数的时候,它须要遍历当前执行环境的做用域链,而遍历是从这个做用域链的前端一级一级的向后遍历,直到全局执行环境,因此这里每每会出现一个状况,那就是若是咱们须要常常访问全局环境的变量对象的时候,咱们每次都必须在当前做用域链上一级一级的遍历,这显然是比较耗时的,咱们看下面的例子:javascript
<
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) +
" 毫秒"
);
}
|
上面代码中,第二种状况是先把全局对象的变量放到函数里面先保存下来,而后直接访问这个变量,而第一种状况是每次都遍历做用域链,直到全局环境,咱们看到第二种状况实际上只遍历了一次,而第一种状况倒是每次都遍历了,因此咱们看看其执行结果:html
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下差异仍是很是明显的,并且这种差异在多级做用域链和多个全局变量的状况下还会表现的很是明显。前端