首頁 >web前端 >js教程 >為JS擴展Array.prototype.indexOf引發的問題及解決方案_基礎知識

為JS擴展Array.prototype.indexOf引發的問題及解決方案_基礎知識

WBOY
WBOY原創
2016-05-16 16:18:361276瀏覽

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

複製程式碼 程式碼如下:

Array.prototype.indexOf = function(item) { 
for (var i = 0; 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] "
"); 
}

本來想輸出這四個人的名字,結果輸出的是什麼呢?

輸出的居然是:

複製程式碼 程式碼如下:

//0=張飛 
//1=關羽 
//2=劉備 
//3=呂布 
//indexOf=function(item) { for (var i = 0; i

除了把名字打出來以外,還額外輸出了自己擴充的方法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; un​​yke the in operator, this object; notnity the in operator, this object; notnity the in operator, this.
看描述,就是我們想要的東西。

在for...in..裡面做個 判斷就OK了

複製程式碼 程式碼如下:
if(a.hasOwnProperty(p)){ 
            document.write(p "=" a[p] "
"); 
        }

另外,附上hasOwnProperty用法範例,來自網路:

複製程式碼 程式碼如下:

函數書(書名,作者){ 
   this.title = 標題; 
   this.author = 作者; 
  } 
   書本.原型.價格 = 9.99; 
   Object.prototype.copyright = "herongyang.com"; 
   var myBook = new Book("JavaScript 教學", "Herong Yang"); 
   // 在基本原型層級轉儲內建屬性
   document.writeln("/nObject.prototype 的內建屬性:"); 
   dumpProperty(Object.prototype, "建構子"); 
   dumpProperty(Object.prototype, "hasOwnProperty"); 
   dumpProperty(Object.prototype, "isPrototypeOf"); 
   dumpProperty(Object.prototype, "toString"); 
   dumpProperty(Object.prototype, "valueOf"); 
   dumpProperty(Object.prototype, "版權"); 
   // 在我的原型層級轉儲內建屬性
   document.writeln("/n==================/nBook.prototype的內建屬性:"); 
   dumpProperty(Book.prototype, "建構子"); 
   dumpProperty(Book.prototype, "hasOwnProperty"); 
   dumpProperty(Book.prototype, "isPrototypeOf"); 
   dumpProperty(Book.prototype, "toString"); 
   dumpProperty(Book.prototype, "valueOf"); 
   dumpProperty(Book.prototype, "版權"); 
   // 在物件層級轉儲內建屬性
   document.writeln("/n==================/nmyBook的內建屬性:"); 
   dumpProperty(myBook,「建構子」); 
   dumpProperty(myBook, "hasOwnProperty"); 
   dumpProperty(myBook, "isPrototypeOf"); 
   dumpProperty(myBook,“toString”); 
   dumpProperty(myBook, "valueOf"); 
   dumpProperty(myBook, "版權"); 
函數 dumpProperty(物件, 屬性) { 
   var 繼承;  
   if (object.hasOwnProperty(property))  
      繼承=「本地」; 
   否則
      繼承=「繼承」; 
   document.writeln(property ": " 繼承 ": "
      物件[屬性]); 
}

查看瀏覽器支援javascript到哪個版本:

複製程式碼程式碼如下:

ttp://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">
http://www.w3.org/1999/xhtml"> 
 
 
  瀏覽器的JavaScript版本支援測試 
  
  
      
     
     
     
     
   
   
   
   
    
  

陳述:
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn