为JS扩展Array.prototype.indexOf引发的问题及解决办法


Posted in Javascript onJanuary 21, 2015

Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了。但是这个自定义的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>
Javascript 相关文章推荐
动态的改变IFrame的高度实现IFrame自动伸展适应高度
Dec 28 Javascript
在Node.js中使用HTTP上传文件的方法
Jun 23 Javascript
JavaScript+CSS实现的可折叠二级菜单实例
Feb 29 Javascript
JavaScript语言精粹经典实例(整理篇)
Jun 07 Javascript
微信小程序 wx.login解密出现乱码的问题解决办法
Mar 10 Javascript
JavaScript制作简单的框选图表
May 15 Javascript
JavaScript实现一个空中避难的小游戏
Jun 06 Javascript
weex里Vuex state使用storage持久化详解
Sep 09 Javascript
浅谈JavaScript 代码整洁之道
Oct 23 Javascript
layui table复选框禁止某几条勾选的实例
Sep 20 Javascript
使用vue cli4.x搭建vue项目的过程详解
May 08 Javascript
Vue+Element ui 根据后台返回数据设置动态表头操作
Sep 21 Javascript
JavaScript的内存释放问题详解
Jan 21 #Javascript
script标签属性用type还是language
Jan 21 #Javascript
JS交换变量的方法
Jan 21 #Javascript
setinterval()与clearInterval()JS函数的调用方法
Jan 21 #Javascript
js实现DOM走马灯特效的方法
Jan 21 #Javascript
浅谈javascript 迭代方法
Jan 21 #Javascript
js实现用户注册协议倒计时的方法
Jan 21 #Javascript
You might like
了解咖啡雨林联盟认证 什么是雨林认证 雨林认证是什么意思
2021/03/05 新手入门
php实现ping
2006/10/09 PHP
PHP下获取上个月、下个月、本月的日期(strtotime,date)
2014/02/02 PHP
详解php中空字符串和0之间的关系
2016/10/23 PHP
php和html的区别点详细总结
2019/09/24 PHP
php操作redis命令及代码实例大全
2020/11/19 PHP
用jquery和json从后台获得数据集的代码
2011/11/07 Javascript
深入理解JavaScript是如何实现继承的
2013/12/12 Javascript
node.js下when.js 的异步编程实践
2014/12/03 Javascript
Angular页面间切换及传值的4种方法
2016/11/04 Javascript
JQuery实现列表中复选框全选反选功能封装(推荐)
2016/11/24 Javascript
nodejs服务搭建教程 nodejs访问本地站点文件
2017/04/07 NodeJs
BootStrap模态框不垂直居中的解决方法
2017/10/19 Javascript
JavaScript 中的12种循环遍历方法【总结】
2018/05/31 Javascript
浅谈Angular7 项目开发总结
2018/12/19 Javascript
详解js常用分割取字符串的方法
2019/05/15 Javascript
了解JavaScript表单操作和表单域
2019/05/27 Javascript
mock.js模拟数据实现前后端分离
2019/07/24 Javascript
JS实现的tab切换并显示相应内容模块功能示例
2019/08/03 Javascript
小程序如何在不同设备上自适应生成海报的实现方法
2019/08/20 Javascript
JS中类的静态方法,静态变量,实例方法,实例变量区别与用法实例分析
2020/03/14 Javascript
Nodejs环境实现socket通信过程解析
2020/07/03 NodeJs
[01:14:30]TNC vs VG 2019国际邀请赛淘汰赛 胜者组赛BO3 第二场 8.20.mp4
2019/08/22 DOTA
python实现mysql的单引号字符串过滤方法
2015/11/14 Python
一步步解析Python斗牛游戏的概率
2016/02/12 Python
Python中Scrapy爬虫图片处理详解
2017/11/29 Python
nginx+uwsgi+django环境搭建的方法步骤
2019/11/25 Python
OpenCV+Python--RGB转HSI的实现
2019/11/27 Python
Pytorch之Variable的用法
2019/12/31 Python
python集合删除多种方法详解
2020/02/10 Python
Python3 中sorted() 函数的用法
2020/03/24 Python
解决keras backend 越跑越慢问题
2020/06/18 Python
Pycharm如何自动生成头文件注释
2020/11/14 Python
简单说说tomcat的配置
2013/05/28 面试题
大学生就业推荐表自我评价
2015/03/02 职场文书
青春雷锋观后感
2015/06/10 职场文书