如何优化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下差异仍是很是明显的,并且这种差异在多级做用域链和多个全局变量的状况下还会表现的很是明显。前端

相关文章
相关标签/搜索