如何優化js代碼(4)——減小做用域鏈上的查找次數

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

相關文章
相關標籤/搜索