JavaScript 對(duì)象的反射及應(yīng)用
??? 作者:Flyingis
??? Java和.NET都有著比較完善的反射機(jī)制,用來(lái)處理未知的對(duì)象并獲取它們的屬性和方法。JavaScript雖然沒(méi)有完善的反射體系,但在編程的時(shí)候還是可以通過(guò)代碼設(shè)計(jì)來(lái)實(shí)現(xiàn)類(lèi)似反射的基本功能。
??? 檢測(cè)一個(gè)JavaScript對(duì)象是否支持某種特定的屬性或方法:

if?(typeof(obj.property)?!=?"undefined")?
{}
??? 這樣聲明比直接使用"if (obj.property)"來(lái)描述要更準(zhǔn)確,因?yàn)楫?dāng)obj.property的值為false、0、null的時(shí)候,雖然該屬性存在,但返回的結(jié)果卻恰恰相反。
??? 如果要求檢測(cè)更詳細(xì)一些,查看該屬性的具體類(lèi)型,可以用instanceof操作符:

if?(obj?instanceof?PredefinedObj)?
{}
??? 但是,當(dāng)對(duì)obj對(duì)象進(jìn)行條件檢測(cè)的時(shí)候,如果多種條件的對(duì)象類(lèi)型存在繼承關(guān)系,則需要注意代碼的書(shū)寫(xiě)順序,例如:

function()?ExamineType(obj)?
{

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

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

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


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

//判斷參數(shù)是否為數(shù)值類(lèi)型

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

//計(jì)算兩個(gè)對(duì)象的重量

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先判斷兩個(gè)對(duì)象是否均存在getWeight()函數(shù),然后檢查getWeight()計(jì)算結(jié)果是否為數(shù)值類(lèi)型,最后進(jìn)行數(shù)值相加返回計(jì)算結(jié)果。需要注意的是,parseFloat(param)函數(shù)能夠除去param中非數(shù)字部分,如果param=16pm,parseFloat(16pm)得到的結(jié)果是16。如果不使用parseFloat(param)函數(shù)對(duì)getWeight()計(jì)算結(jié)果進(jìn)行檢驗(yàn),那么會(huì)帶來(lái)安全性的問(wèn)題,這種情況下可以將對(duì)象的getWeight()設(shè)計(jì)為返回字符串或其他類(lèi)型,在調(diào)用它之前我們是不知道JavaScript函數(shù)的返回類(lèi)型的,因?yàn)镴avaScript函數(shù)沒(méi)有預(yù)先定義的類(lèi)型。
??? Java和.NET都有著比較完善的反射機(jī)制,用來(lái)處理未知的對(duì)象并獲取它們的屬性和方法。JavaScript雖然沒(méi)有完善的反射體系,但在編程的時(shí)候還是可以通過(guò)代碼設(shè)計(jì)來(lái)實(shí)現(xiàn)類(lèi)似反射的基本功能。
??? 檢測(cè)一個(gè)JavaScript對(duì)象是否支持某種特定的屬性或方法:



??? 這樣聲明比直接使用"if (obj.property)"來(lái)描述要更準(zhǔn)確,因?yàn)楫?dāng)obj.property的值為false、0、null的時(shí)候,雖然該屬性存在,但返回的結(jié)果卻恰恰相反。
??? 如果要求檢測(cè)更詳細(xì)一些,查看該屬性的具體類(lèi)型,可以用instanceof操作符:



??? 但是,當(dāng)對(duì)obj對(duì)象進(jìn)行條件檢測(cè)的時(shí)候,如果多種條件的對(duì)象類(lèi)型存在繼承關(guān)系,則需要注意代碼的書(shū)寫(xiě)順序,例如:














??? 上述代碼執(zhí)行的結(jié)果會(huì)認(rèn)為原為Array類(lèi)型的obj是一個(gè)Object,因?yàn)锳rray本身就是從Object繼承而來(lái),顯然,將對(duì)Array的檢測(cè)放在前面會(huì)得到更精確的結(jié)果。因此,使用instanceof來(lái)判斷對(duì)象類(lèi)型,需要注意當(dāng)兩個(gè)對(duì)象存在繼承關(guān)系的時(shí)候,應(yīng)該關(guān)注檢測(cè)順序的問(wèn)題,進(jìn)一步我們可以想到,JSON創(chuàng)建的對(duì)象不是Object就是Array,使用instanceof來(lái)檢測(cè)JSON對(duì)象意義不大。
??? 利用JavaScript的反射,我們可以編寫(xiě)一個(gè)函數(shù)來(lái)檢查對(duì)象是否有一個(gè)特定名稱的函數(shù),然后利用該函數(shù)進(jìn)行計(jì)算,以此在JavaScript中實(shí)現(xiàn)接口的功能,為在Ajax中使用設(shè)計(jì)模式奠定基礎(chǔ)。







































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