讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議177:避免深陷作用域訪問 >

建議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對象。如果存在大量的這種對對像深層屬性的訪問,那麼可以參照以上方式提高性能。