JavaScript 對象的反射及應用
??? 作者:Flyingis
??? Java和.NET都有著比較完善的反射機制,用來處理未知的對象并獲取它們的屬性和方法。JavaScript雖然沒有完善的反射體系,但在編程的時候還是可以通過代碼設計來實現類似反射的基本功能。
??? 檢測一個JavaScript對象是否支持某種特定的屬性或方法:

if?(typeof(obj.property)?!=?"undefined")?
{}
??? 這樣聲明比直接使用"if (obj.property)"來描述要更準確,因為當obj.property的值為false、0、null的時候,雖然該屬性存在,但返回的結果卻恰恰相反。
??? 如果要求檢測更詳細一些,查看該屬性的具體類型,可以用instanceof操作符:

if?(obj?instanceof?PredefinedObj)?
{}
??? 但是,當對obj對象進行條件檢測的時候,如果多種條件的對象類型存在繼承關系,則需要注意代碼的書寫順序,例如:

function()?ExamineType(obj)?
{

??if?(obj?instanceof?Object)?
{
????alert("An?Object");

??else?if?(obj?instanceof?Array)?
{
????alert("An?Array");
??}
??}
}
??? 上述代碼執行的結果會認為原為Array類型的obj是一個Object,因為Array本身就是從Object繼承而來,顯然,將對Array的檢測放在前面會得到更精確的結果。因此,使用instanceof來判斷對象類型,需要注意當兩個對象存在繼承關系的時候,應該關注檢測順序的問題,進一步我們可以想到,JSON創建的對象不是Object就是Array,使用instanceof來檢測JSON對象意義不大。
??? 利用JavaScript的反射,我們可以編寫一個函數來檢查對象是否有一個特定名稱的函數,然后利用該函數進行計算,以此在JavaScript中實現接口的功能,為在Ajax中使用設計模式奠定基礎。
//this.getWeight和this["getWeight"]意義相同
//判斷對象是否存在指定名稱的函數

Object.prototype.hasFunc?=?function(func)?
{
??return?this?&&?this[func]?&&?this[func]?instanceof?Function;
}


function?hasWeight(obj)?
{
??return?obj.hasFunc("getWeight");
}

//判斷參數是否為數值類型

function?isNum(param)?
{
??return?parseFloat(param)?!=?NaN;
}

//計算兩個對象的重量

function?calWeight(obj1,?obj2)?
{
??var?total?=?null;

??if?(hasWeight(obj1)?&&?hasWeight(obj2))?
{
????var?w1?=?obj1.getWeight();
????var?w2?=?obj2.getWeight();

????if?(isNum(w1)?&&?isNum(w2))?
{
??????total?=?parseFloat(w1)?+?parseFloat(w2);
????}
??}
??return?total;
}
??? calWeight先判斷兩個對象是否均存在getWeight()函數,然后檢查getWeight()計算結果是否為數值類型,最后進行數值相加返回計算結果。需要注意的是,parseFloat(param)函數能夠除去param中非數字部分,如果param=16pm,parseFloat(16pm)得到的結果是16。如果不使用parseFloat(param)函數對getWeight()計算結果進行檢驗,那么會帶來安全性的問題,這種情況下可以將對象的getWeight()設計為返回字符串或其他類型,在調用它之前我們是不知道JavaScript函數的返回類型的,因為JavaScript函數沒有預先定義的類型。
??? Java和.NET都有著比較完善的反射機制,用來處理未知的對象并獲取它們的屬性和方法。JavaScript雖然沒有完善的反射體系,但在編程的時候還是可以通過代碼設計來實現類似反射的基本功能。
??? 檢測一個JavaScript對象是否支持某種特定的屬性或方法:



??? 這樣聲明比直接使用"if (obj.property)"來描述要更準確,因為當obj.property的值為false、0、null的時候,雖然該屬性存在,但返回的結果卻恰恰相反。
??? 如果要求檢測更詳細一些,查看該屬性的具體類型,可以用instanceof操作符:



??? 但是,當對obj對象進行條件檢測的時候,如果多種條件的對象類型存在繼承關系,則需要注意代碼的書寫順序,例如:














??? 上述代碼執行的結果會認為原為Array類型的obj是一個Object,因為Array本身就是從Object繼承而來,顯然,將對Array的檢測放在前面會得到更精確的結果。因此,使用instanceof來判斷對象類型,需要注意當兩個對象存在繼承關系的時候,應該關注檢測順序的問題,進一步我們可以想到,JSON創建的對象不是Object就是Array,使用instanceof來檢測JSON對象意義不大。
??? 利用JavaScript的反射,我們可以編寫一個函數來檢查對象是否有一個特定名稱的函數,然后利用該函數進行計算,以此在JavaScript中實現接口的功能,為在Ajax中使用設計模式奠定基礎。







































??? calWeight先判斷兩個對象是否均存在getWeight()函數,然后檢查getWeight()計算結果是否為數值類型,最后進行數值相加返回計算結果。需要注意的是,parseFloat(param)函數能夠除去param中非數字部分,如果param=16pm,parseFloat(16pm)得到的結果是16。如果不使用parseFloat(param)函數對getWeight()計算結果進行檢驗,那么會帶來安全性的問題,這種情況下可以將對象的getWeight()設計為返回字符串或其他類型,在調用它之前我們是不知道JavaScript函數的返回類型的,因為JavaScript函數沒有預先定義的類型。
posted on 2006-09-12 18:50 Flyingis 閱讀(5857) 評論(5) 編輯 收藏 所屬分類: Web 客戶端技術