天天看點

擴充Array.prototype.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>

繼續閱讀