四、減小做用域鏈上的查找次數
咱們知道,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下差異仍是很是明顯的,並且這種差異在多級做用域鏈和多個全局變量的狀況下還會表現的很是明顯。前端