聯(lián)合數(shù)組以及Prototype的風(fēng)險(xiǎn)
Associative Arrays and the Risks of Prototype
JavaScript的對(duì)象都可以作為聯(lián)合數(shù)組(associative arrays,也稱為哈希、哈希結(jié)構(gòu)或者哈希表)。這就意味著你可以使用點(diǎn)符號(hào)來(lái)訪問(wèn)一個(gè)對(duì)象屬性:
someObject.objProperty
你還可以使用數(shù)組符號(hào)訪問(wèn)一個(gè)屬性,給出屬性名稱作為索引:
someObject["objProperty"]
在鍵值對(duì)之間進(jìn)行映射是聯(lián)合數(shù)組固有的特征。由于JavaScript對(duì)象可以作為聯(lián)合數(shù)組,所以你也可以使用JavaScript的for...in語(yǔ)句來(lái)迭代對(duì)象的屬性:
for (props in obj) {...}
你還可以利用任何JavaScript對(duì)象,來(lái)建立一個(gè)新的聯(lián)合數(shù)組,包括Array、RegExp、Object、String等。如下代碼就使用了Array對(duì)象,這也是非常恰當(dāng)?shù)挠梅ǎ?/span>
var newArray = new Array();
newArray['1'] = 'one';
newArray['3'] = 'three';
它看上去非常簡(jiǎn)單,但是,這在那些使用JavaScript的人,尤其是使用Prototype的人之間會(huì)引發(fā)一些非常激烈的爭(zhēng)論。
有些人會(huì)說(shuō),在JavaScript中沒(méi)有聯(lián)合數(shù)組,這種功能只不過(guò)是添加運(yùn)行期屬性的一種方式罷了。但是,暫且不說(shuō)語(yǔ)義如何,這種功能和聯(lián)合數(shù)組是相匹配的(數(shù)組元素是由鍵或者名稱,而不是由數(shù)字來(lái)指定的),因此,從各個(gè)方面來(lái)說(shuō),它都是聯(lián)合數(shù)組。
還有些人說(shuō),在JavaScript中使用聯(lián)合數(shù)組是錯(cuò)誤的,或者是有害的。他們解釋說(shuō):使用Array對(duì)象建立一個(gè)聯(lián)合數(shù)組,違反了自然規(guī)律——通常給你提供有關(guān)數(shù)組信息的方法就不再工作了,例如:長(zhǎng)度,并且我們應(yīng)該僅僅將Array對(duì)象,用于傳統(tǒng)的數(shù)字?jǐn)?shù)組來(lái)支持可預(yù)料的行為。
對(duì)于Prototype來(lái)說(shuō),這是一個(gè)相當(dāng)尖銳的問(wèn)題,因?yàn)樗ㄟ^(guò)prototype屬性擴(kuò)展了基本的Array對(duì)象。如果你從Array對(duì)象建立一個(gè)聯(lián)合數(shù)組,而Prototype這樣的庫(kù)會(huì)擴(kuò)展聯(lián)合數(shù)組本身,那么當(dāng)你使用for...in來(lái)查詢它時(shí),你可能會(huì)得到不可預(yù)料的結(jié)果,而且很有可能會(huì)導(dǎo)致應(yīng)用程序中斷。
為了取代使用Array作為聯(lián)合數(shù)組這種方式,一些Ajax專家建議使用Object。在Prototype 1.4版本中也使用了prototype屬性,擴(kuò)展了JavaScript中基本的Object,但Stephenson又把它從1.5版本中剔除了。因此它仍舊擴(kuò)展了String、Array以及其他對(duì)象,如果使用聯(lián)合數(shù)組功能來(lái)訪問(wèn)應(yīng)用程序中的對(duì)象屬性,你就應(yīng)該清楚這些內(nèi)容。
警告:你也需要非常清楚prototype的擴(kuò)展能力,如果你正在使用多個(gè)庫(kù),它們各自都有可能在原始的JavaScript對(duì)象上建立自己的擴(kuò)展。這些庫(kù)之間的沖突可能會(huì)導(dǎo)致一些很難調(diào)試而且又不可思議的問(wèn)題。
聯(lián)系客服