為JS擴充Array.prototype.indexOf引發的問題探討及解決

來源:互聯網
上載者:User

Array沒有indexOf方法,這樣在一個數組中尋找某個元素的索引時比較麻煩,為了調用方便,於是通過prototype原型擴充了Array.prototype.indexOf(),這樣用起來就比較方便了。但是這個自訂的indexOf在對數組進行遍曆的時候卻出現了問題。

Array沒有indexOf方法,這樣在一個數組中尋找某個元素的索引時比較麻煩,為了調用方便,於是通過prototype原型擴充了Array.prototype.indexOf(),這樣用起來就比較方便了。
複製代碼 代碼如下:
Array.prototype.indexOf = function(item) {
for (var i = 0; i < this.length; i++) {
if (this[i] == item)
return i;
}
return -1;
}

用的時候直接
複製代碼 代碼如下:
var arr=[1,2,3,4,5];
var index=arr.indexOf(1); //index==0

擴充了以後,用起來很爽很方便,一片和諧景象...
但是某次是遍曆數組元素的時候,使用for..in..迴圈,引發了其他的問題,打破了這個和諧的氛圍。
複製代碼 代碼如下:
var a=["張飛","關羽","劉備","呂布"];
for(var p in a){
document.write(p+"="+a[p]+"<br/>");
}

本來想輸出這四個人的名字,結果輸出的是什麼呢?
輸出的居然是:
//0=張飛
//1=關羽
//2=劉備
//3=呂布
//indexOf=function(item) { for (var i = 0; i < this.length; i++) { if (this[i] == item) return i; } return -1; }
除了把名字打出來以外,還額外輸出了自己擴充的方法indexOf,但是令人瘋狂的是,firefox卻是“正常”的,只有四個人的人名,為什麼會這樣?
輸出indexOf,自己擴充的,可以理解,畢竟for..in是遍曆一個對象的所有使用者定義的屬性或者一個數組的所有元素。
那麼firefox為什麼不會?
後來查了資料才明白,
Array在javascript1.6版本已經支援Array.indexOf(),而我用的firefox是3.5版本,已經支援javascript1.8了,indexOf是其Array本身固有的方法了。
而IE,即使我用的是IE8,也才支援到javascript1.3版本。
所以IE8認為indexOf是“使用者定義的屬性”,而firefox認為是自己原生支援的固有的屬性。
真的是這樣嗎?
做個實驗,把indexOf更名為myIndexOf,再試試,結果IE和firefox都輸出myIndexOf,證明前面的觀點是正確。
那麼又來了個問題,我擴充indexOf很久了,現在不少項目的代碼都已經在使用這個方法,而現在我非要使用for..in輸出數組本身的元素,不要其他我自己擴充到俄方法,怎麼辦?
好在javascript提供了hasOwnProperty方法。
看一下其描述:
Every object descended from Object inherits the hasOwnProperty method. This method can be used to determine whether an object has the specified property as a direct property of that object; unlike the in operator, this method does not check down the object's prototype chain
看描述,就是我們想要的東西。
在for...in..裡做個 判斷就OK了
複製代碼 代碼如下:
if(a.hasOwnProperty(p)){
document.write(p+"="+a[p]+"<br/>");
}

另外,附上hasOwnProperty用法樣本,來源於互連網:
複製代碼 代碼如下:
function Book(title, author) {
this.title = title;
this.author = author;
}
Book.prototype.price = 9.99;
Object.prototype.copyright = "herongyang.com";
var myBook = new Book("JavaScript Tutorials", "Herong Yang");
// Dumping built-in properties at the base prototype level
document.writeln("/nObject.prototype's built-in properties:");
dumpProperty(Object.prototype, "constructor");
dumpProperty(Object.prototype, "hasOwnProperty");
dumpProperty(Object.prototype, "isPrototypeOf");
dumpProperty(Object.prototype, "toString");
dumpProperty(Object.prototype, "valueOf");
dumpProperty(Object.prototype, "copyright");
// Dumping built-in properties at the my prototype level
document.writeln("/n==================/nBook.prototype's built-in properties:");
dumpProperty(Book.prototype, "constructor");
dumpProperty(Book.prototype, "hasOwnProperty");
dumpProperty(Book.prototype, "isPrototypeOf");
dumpProperty(Book.prototype, "toString");
dumpProperty(Book.prototype, "valueOf");
dumpProperty(Book.prototype, "copyright");
// Dumping built-in properties at the object level
document.writeln("/n==================/nmyBook's built-in properties:");
dumpProperty(myBook, "constructor");
dumpProperty(myBook, "hasOwnProperty");
dumpProperty(myBook, "isPrototypeOf");
dumpProperty(myBook, "toString");
dumpProperty(myBook, "valueOf");
dumpProperty(myBook, "copyright");
function dumpProperty(object, property) {
var inheritance;
if (object.hasOwnProperty(property))
inheritance = "Local";
else
inheritance = "Inherited";
document.writeln(property+": "+inheritance+": "
+object[property]);
}

查看瀏覽器支援javascript到哪個版本:
複製代碼 代碼如下:
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8" />
<title>瀏覽器的JavaScript版本支援測試</title>
</head>
<body>
<script language="JavaScript">
//document.write("您的瀏覽器類型:"+navigator.appName+"<br/>");
//document.write("瀏覽器版本:"+navigator.appVersion+"<br/>");
//支援JavaScript1.0的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.0<br/>');
</script>
<script language="JavaScript1.1">
//支援JavaScript1.1的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.1<br/>');
</script>
<script language="JavaScript1.2">
//支援JavaScript1.2的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.2<br/>');
</script>
<script language="JavaScript1.3">
//支援JavaScript1.3的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.3<br/>');
</script>
<script language="JavaScript1.4">
//支援JavaScript1.4的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.4<br/>');
</script>
<script language="JavaScript1.5">
//支援JavaScript1.5的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.5<br/>');
</script>
<script language="JavaScript1.6">
//支援JavaScript1.6的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.6<br/>');
</script>
<script language="JavaScript1.7">
//支援JavaScript1.7的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.7<br/>');
</script>
<script language="JavaScript1.8">
//支援JavaScript 1.8的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.8<br/>');
</script>
<script language="JavaScript1.9">
//支援JavaScript1.9的瀏覽器才能夠執行該指令碼
document.write('該瀏覽器支援JavaScript1.9<br/>');
</script>
</body>
</html>

相關文章

聯繫我們

該頁面正文內容均來源於網絡整理,並不代表阿里雲官方的觀點,該頁面所提到的產品和服務也與阿里云無關,如果該頁面內容對您造成了困擾,歡迎寫郵件給我們,收到郵件我們將在5個工作日內處理。

如果您發現本社區中有涉嫌抄襲的內容,歡迎發送郵件至: info-contact@alibabacloud.com 進行舉報並提供相關證據,工作人員會在 5 個工作天內聯絡您,一經查實,本站將立刻刪除涉嫌侵權內容。

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.