为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 相关文章推荐
方便实用的jQuery checkbox复选框全选功能简单实例
Oct 09 Javascript
jQuery增加和删除表格项目及实现表格项目排序的方法
May 30 Javascript
JavaScript两个变量交换值的实现方法
Mar 01 Javascript
Vue插件写、用详解(附demo)
Mar 20 Javascript
IntersectionObserver实现图片懒加载的示例
Sep 29 Javascript
使用vue + less 实现简单换肤功能的示例
Feb 21 Javascript
JavaScript正则表达式函数总结(常用)
Feb 22 Javascript
浅谈Vue下使用百度地图的简易方法
Mar 23 Javascript
微信小程序下拉框功能的实例代码
Nov 06 Javascript
小程序封装路由文件和路由方法(5种全解析)
May 26 Javascript
浅谈vue项目利用Hbuilder打包成APP流程,以及遇到的坑
Sep 12 Javascript
利用JavaScript写一个简单计算器
Nov 27 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
用PHP调用Oracle存储过程
2006/10/09 PHP
判断PHP数组是否为空的代码
2011/09/08 PHP
不要小看注释掉的JS 引起的安全问题
2008/12/27 Javascript
详解JS 比较两个Json对象的值是否相等的实例
2013/11/20 Javascript
JS网页图片按比例自适应缩放实现方法
2014/01/15 Javascript
jQuery中:first-child选择器用法实例
2014/12/31 Javascript
js 获取元素在页面上的偏移量的方法汇总
2015/04/13 Javascript
javascript获取重复次数最多的字符
2015/07/08 Javascript
javascript图片切换综合实例(循环切换、顺序切换)
2016/01/13 Javascript
js中常用的Tab切换效果(推荐)
2016/08/30 Javascript
JS/jquery实现一个网页内同时调用多个倒计时的方法
2017/04/27 jQuery
深入理解Angularjs中$http.post与$.post
2017/05/19 Javascript
js判断输入框不能为空格或null值的实现方法
2018/03/02 Javascript
Vue基础学习之项目整合及优化
2019/06/02 Javascript
jQuery实现checkbox全选、反选及删除等操作的方法详解
2019/08/02 jQuery
vue 微信扫码登录(自定义样式)
2020/01/06 Javascript
vue 使用 vue-pdf 实现pdf在线预览的示例代码
2020/04/26 Javascript
[52:57]2014 DOTA2国际邀请赛中国区预选赛 LGD-CDEC VS HGT
2014/05/21 DOTA
利用python获取某年中每个月的第一天和最后一天
2016/12/15 Python
Python实现登陆文件验证方法
2018/10/06 Python
Python读取txt某几列绘图的方法
2018/10/14 Python
基于Python批量生成指定尺寸缩略图代码实例
2019/11/20 Python
Python tkinter 下拉日历控件代码
2020/03/04 Python
Windows10+anacond+GPU+pytorch安装详细过程
2020/03/24 Python
使用 prometheus python 库编写自定义指标的方法(完整代码)
2020/06/29 Python
Python调用SMTP服务自动发送Email的实现步骤
2021/02/07 Python
英国最大的在线床超市:Bed Star
2019/01/24 全球购物
伦敦著名的运动鞋综合商店:Footpatrol
2019/03/25 全球购物
捷克街头、运动和滑板一站式商店:BoardStar.cz
2019/10/06 全球购物
shallow copy和deep copy的区别
2016/05/09 面试题
模具专业推荐信
2013/10/30 职场文书
统计学专业毕业生的自我评价分享
2013/11/28 职场文书
公司成立感言
2014/01/11 职场文书
cf收人广告词大全
2014/03/14 职场文书
考生诚信考试承诺书
2015/04/29 职场文书
教你怎么用python实现字符串转日期
2021/05/24 Python