首页 » 编写高质量代码:改善JavaScript程序的188个建议 » 编写高质量代码:改善JavaScript程序的188个建议全文在线阅读

《编写高质量代码:改善JavaScript程序的188个建议》建议177:避免深陷作用域访问

关灯直达底部

JavaScript代码的解释执行在进入函数内部时会预先分析当前的变量,并且将这些变量归入不同的层级。局部变量放入层级1(浅),全局变量放入层级2(深)。如果进入with或try/catch代码块,则会增加新的层级,也就是将with或catch中的变量放入最浅层(层级1),并且将之前的层级依次加深。


var myObj;

function process{

var images=document.getElementsByTagName("img"),widget=document.

getElementsByTagName("input"),combination=;

for(var i=0;i<images.length;i++){

combination.push(combine(images[i],widget[2*i]));

}

myObj.container.property1=combination[0];

myObj.container.property2=combination[combination.length-1];

}


在上面代码中,images、widget、combination属于局部变量,位于层级1。document、myObj属于全局变量,位于层级2。变量所在的层越浅,访问速度越快,变量所在的层越深,访问速度越慢,所以这里对images、widget、combination的访问速度比document、myObj要快一些。推荐使用局部变量,例如:


var myObj;

function process{

var doc=document;

var images=doc.getElementsByTagName("im g"),widget=doc.getElementsByTagName("input"),combination=;

for(var i=0;i<images.length;i++){

combination.push(combine(images[i],widget[2*i]));

}

myObj.container.property1=combination[0];

myObj.container.property2=combination[combination.length-1];

}


使用局部变量doc取代全局变量document,这样可以改进性能,尤其是在大量使用全局变量的函数中。再看下面代码:


var myObj;

function process{

var doc=document;

var images=doc.getElementsByTagName("img"),widget=doc.getElementsByTagName("input"),combination=;

for(var i=0;i<images.length;i++){

combination.push(combine(images[i],widget[2*i]));

}

with(myObj.container){

property1=combination[0];

property2=combination[combination.length-1];

}

}


加上with语句结构,可以让代码更加简洁清晰,但这样做会使性能受影响。正如之前说的,当进入with代码块时,combination便从原来的层级1变到了层级2,这样效率会大大降低。因此,优化with语句,推荐使用下面代码。


var myObj;

function process{

var doc=document;

var images=doc.getElementsByTagName("img"),widget=doc.

getElementsByTagName("input"),combination=;

for(var i=0;i<images.length;i++){

combination.push(combine(images[i],widget[2*i]));

}

myObj.container.property1=combination[0];

myObj.container.property2=combination[combination.length-1];

}


但这样并不是最好的方式,JavaScript有个特点,对于object对象来说,其属性访问层级越深,效率越低。如果这里的myObj已经访问到了第3层,那么可以这样改进一下来缩小对象访问层级:


var myObj;

function process{

var doc=document;

var images=doc.getElementsByTagName("img"),widget=doc.getElementsByTagName("input"),combination=;

for(var i=0;i<images.length;i++){

combination.push(combine(images[i],widget[2*i]));

}

var ctn=myObj.container;

ctn.property1=combination[0];

ctn.property2=combination[combination.length-1];

}


用局部变量来代替myObj第2层的container对象。如果存在大量的这种对对象深层属性的访问,那么可以参照以上方式提高性能。