讀古今文學網 > 編寫高質量代碼:改善JavaScript程序的188個建議 > 建議84:防止原型反射 >

建議84:防止原型反射

檢查對象並確定對像有什麼屬性是很容易的事情,只要試著去檢索對像屬性並驗證取得的值即可。同時,使用typeof操作符可以判斷屬性的類型。


typeof obj.number//'number'

typeof obj.status//'string'

typeof obj.name//'undefined'


但是,根據原型繼承的關係,原型鏈中的所有屬性也會產生反射,這種反射稱為原型反射。


typeof obj.toString//'function'

typeof obj.constructor//'function'


為了避免原型繼承的干擾,有兩種方法可用於處理這些不需要的屬性:

❑編寫程序進行檢查並剔除函數值。一般來說,對像反射的目標是讀取對像包含的數據,因此當對像成員值為函數時,一般都不是我們需要的數據。

❑使用hasOwnProperty方法。如果對像擁有獨有的屬性,那麼調用該方法將返回true,也就是說,hasOwnProperty方法不會檢查原型鏈。


obj.hasOwnProperty('number')//true

obj.hasOwnProperty('constructor')//false


要快速枚舉對象的所有屬性,可以使用for in語句。該語句可遍歷對像中的所有屬性名,枚舉過程將會列出所有的屬性,包括方法和原型屬性。因此,在枚舉過程中,必須過濾掉那些不想要的值,具體方法如下:

❑使用hasOwnProperty方法過濾原型屬性。

❑使用typeof運算符排除方法函數。

例如:


var name;

for(name in obj){

if(typeof obj[name]!=='function'){

document.writeln(name+':'+obj[name]);

}

}


當使用for in語句枚舉對像時,由於屬性名出現的順序是不確定的,因此要對任何可能出現的順序有所準備。要確保屬性以特定的順序出現,最好的辦法就是避免使用for in語句,創建一個數組,在其中以正確的順序包含屬性名。


var i;

var properties=['one','two','three','four'];

for(i=0;i<properties.length;i+=1){

document.writeln(properties[i]+':'+obj[properties[i]]);

}


通過使用for而不是for in可以枚舉需要的屬性,從而不用擔心可能反射到原型鏈中的屬性,並且可以按正確的順序取得它們的值。