为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 相关文章推荐
JavaScript 事件属性绑定带参数的函数
Mar 13 Javascript
jquery的ajax从纯真网(cz88.net)获取IP地址对应地区名
Dec 02 Javascript
JavaScript浏览器选项卡效果
Aug 25 Javascript
JavaScript将字符串转换为整数的方法
Apr 14 Javascript
javascript控制层显示或隐藏的方法
Jul 22 Javascript
整理关于Bootstrap列表组的慕课笔记
Mar 29 Javascript
JS跳转手机站url的若干注意事项
Oct 18 Javascript
Vue-Router的使用方法
Sep 05 Javascript
微信小程序之数据绑定原理解析
Aug 14 Javascript
layui原生表单验证的实例
Sep 09 Javascript
layui之数据表格--与后台交互获取数据的方法
Sep 29 Javascript
uniapp微信小程序实现一个页面多个倒计时
Nov 01 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
PHP+MySQL 制作简单的留言本
2009/11/02 PHP
Linux下实现PHP多进程的方法分享
2012/08/16 PHP
php另类上传图片的方法(PHP用Socket上传图片)
2013/10/30 PHP
PHP数据库操作之基于Mysqli的数据库操作类库
2014/04/19 PHP
PHP实现抓取Google IP并自动修改hosts文件
2015/02/12 PHP
PHP编程之设置apache虚拟目录
2016/07/08 PHP
PHP 5.6.11中CURL模块问题的解决方法
2016/08/08 PHP
基于ThinkPHP5.0实现图片上传插件
2017/09/25 PHP
PHP实现腾讯短网址生成api接口实例
2020/12/08 PHP
IE与Firefox下javascript getyear年份的兼容性写法
2007/12/20 Javascript
js对象关系图 方便dom操作
2012/03/18 Javascript
jquery操作HTML5 的data-*的用法实例分享
2014/08/17 Javascript
jQuery 获取select选中值及清除选中状态
2016/12/13 Javascript
canvas快速绘制圆形、三角形、矩形、多边形方法介绍
2016/12/29 Javascript
vue拦截器Vue.http.interceptors.push使用详解
2017/04/22 Javascript
vue中子组件的methods中获取到props中的值方法
2018/08/27 Javascript
利用Dectorator分模块存储Vuex状态的实现
2019/02/05 Javascript
Node.js Stream ondata触发时机与顺序的探索
2019/03/08 Javascript
JS操作字符串转数字的常见方法示例
2019/10/29 Javascript
vue-cli3.0实现一个多页面应用的历奇经历记录总结
2020/03/16 Javascript
js防抖函数和节流函数使用场景和实现区别示例分析
2020/04/11 Javascript
eslint+prettier统一代码风格的实现方法
2020/07/22 Javascript
vue+echarts实现中国地图流动效果(步骤详解)
2021/01/27 Vue.js
python之yield表达式学习
2014/09/02 Python
python支付宝支付示例详解
2019/08/22 Python
html5手机键盘弹出收起的处理
2020/01/20 HTML / CSS
YSL圣罗兰美妆官方旗舰店:购买YSL口红
2018/04/16 全球购物
C#如何判断当前用户是否输入某个域
2015/12/07 面试题
历史专业毕业生的自我鉴定
2013/11/15 职场文书
信用社竞聘演讲稿
2014/05/16 职场文书
机械加工与数控专业自荐书
2014/06/04 职场文书
动物科学专业求职信
2014/07/27 职场文书
2014年残联工作总结
2014/11/21 职场文书
通知书大全
2015/04/27 职场文书
小学生红领巾广播稿
2015/08/19 职场文书
合作协议书格式范本
2016/03/21 职场文书