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


Posted in Javascript onApril 24, 2013

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>
Javascript 相关文章推荐
ExtJS扩展 垂直tabLayout实现代码
Jun 21 Javascript
javascript 二维数组的实现与应用
Mar 16 Javascript
让JavaScript拥有类似Lambda表达式编程能力的方法
Sep 12 Javascript
js简单的表格添加行和删除行操作示例
Mar 31 Javascript
深入浅析同源策略和跨域访问
Nov 26 Javascript
BootstrapTable+KnockoutJS自定义T4模板快速生成增删改查页面
Aug 01 Javascript
纯js实现的积木(div层)拖动功能示例
Jul 19 Javascript
vue基于Element构建自定义树的示例代码
Sep 19 Javascript
基于webpack 实用配置方法总结
Sep 28 Javascript
js+SVG实现动态时钟效果
Jul 14 Javascript
JavaScript基础教程之如何实现一个简单的promise
Sep 11 Javascript
js+canvas实现简单扫雷小游戏
Jan 22 Javascript
Dom 学习总结以及实例的使用介绍
Apr 24 #Javascript
jQuery 关于伪类选择符的使用说明
Apr 24 #Javascript
关于ExtJS4.1:快捷键支持的问题
Apr 24 #Javascript
Jquery实现三层遍历删除功能代码
Apr 23 #Javascript
jQuery获取浏览器中的分辨率实现代码
Apr 23 #Javascript
使用PHP+JQuery+Ajax分页的实现
Apr 23 #Javascript
jQuery写的日历(包括日历的样式及功能)
Apr 23 #Javascript
You might like
咖啡的植物学知识
2021/03/03 咖啡文化
php MsSql server时遇到的中文编码问题
2009/06/11 PHP
如何在symfony中导出为CSV文件中的数据
2011/10/06 PHP
php使用百度ping服务代码实例
2014/06/19 PHP
脚本吧 - 幻宇工作室用到js,超强推荐expand.js
2006/12/23 Javascript
网页自动刷新,不产生嗒嗒声的一个解决方法
2007/03/27 Javascript
早该知道的7个JavaScript技巧
2013/03/27 Javascript
JavaScript用Number方法实现string转int
2014/05/13 Javascript
js选项卡的实现方法
2015/02/09 Javascript
JS实现带关闭功能的阿里妈妈网站顶部滑出banner工具条代码
2015/09/17 Javascript
Bootstrap每天必学之面板
2015/11/30 Javascript
javascript中this指向详解
2016/04/23 Javascript
深入浅析JavaScript函数前面的加号和叹号
2016/07/09 Javascript
angularjs ocLazyLoad分步加载js文件实例
2017/01/17 Javascript
jquery实现下拉菜单的手风琴效果
2017/07/23 jQuery
详解小程序不同页面之间通讯的解决方案
2018/11/23 Javascript
微信小程序实现吸顶效果
2020/01/08 Javascript
Vue数据双向绑定原理实例解析
2020/05/15 Javascript
微信小程序中的列表切换功能实例代码详解
2020/06/09 Javascript
Python用Bottle轻量级框架进行Web开发
2016/06/08 Python
python字符串str和字节数组相互转化方法
2017/03/18 Python
Python导入模块时遇到的错误分析
2017/08/30 Python
Python使用Selenium+BeautifulSoup爬取淘宝搜索页
2018/02/24 Python
pycharm重置设置,恢复默认设置的方法
2018/10/22 Python
一篇文章搞懂Python的类与对象名称空间
2018/12/10 Python
利用Python正则表达式过滤敏感词的方法
2019/01/21 Python
关于python中密码加盐的学习体会小结
2019/07/15 Python
pytorch多进程加速及代码优化方法
2019/08/19 Python
python3图片文件批量重命名处理
2019/10/31 Python
python脚本定时发送邮件
2020/12/22 Python
Python 实现一个简单的web服务器
2021/01/03 Python
Daisy London官网:英国最大的首饰集团IBB旗下
2019/02/28 全球购物
家长学校工作方案
2014/05/07 职场文书
趣味运动会通讯稿
2015/07/18 职场文书
助学金申请书该怎么写?
2019/07/16 职场文书
instantclient客户端 连接oracle数据库
2022/04/26 Oracle