为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 相关文章推荐
DD_belatedPNG,IE6下PNG透明解决方案(国外)
Dec 06 Javascript
extjs表格文本启用选择复制功能具体实现
Oct 11 Javascript
jqgrid 表格数据导出实例
Nov 21 Javascript
开发中可能会用到的jQuery小技巧
Mar 07 Javascript
jquery搜索框效果实现方法
Jan 16 Javascript
jQuery使用之标记元素属性用法实例
Jan 19 Javascript
webpack学习--webpack经典7分钟入门教程
Jun 28 Javascript
DataTables添加额外的查询参数和删除columns等无用参数实例
Jul 04 Javascript
Node接收电子邮件的实例代码
Jul 21 Javascript
小程序接口的promise化的实现方法
Dec 11 Javascript
微信小程序开发(一):服务器获取数据列表渲染操作示例
Jun 01 Javascript
JavaScript中CreateTextFile函数
Aug 30 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如何抛出异常处理错误
2011/03/02 PHP
php从完整文件路径中分离文件目录和文件名的方法
2015/03/13 PHP
php实现微信公众号无限群发
2015/10/11 PHP
PHP调用存储过程返回值不一致问题的解决方法分析
2016/04/26 PHP
那些年,我还在学习jquery 学习笔记
2012/03/05 Javascript
使用jQuery fancybox插件打造一个实用的数据传输模态弹出窗体
2013/01/15 Javascript
解析jquery中的ajax缓存问题
2013/12/19 Javascript
深入理解JavaScript系列(36):设计模式之中介者模式详解
2015/03/04 Javascript
九种原生js动画效果
2015/11/11 Javascript
jQuery实现模拟flash头像裁切上传功能示例
2016/12/11 Javascript
JS实现上传图片实时预览功能
2017/05/22 Javascript
vue.js过滤器+ajax实现事件监听及后台php数据交互实例
2018/05/22 Javascript
vue 项目build错误异常的解决方法
2019/04/22 Javascript
js Math数学简单使用操作示例
2020/03/13 Javascript
基于leaflet.js实现修改地图主题样式的流程分析
2020/05/15 Javascript
JS如何实现封装列表右滑动删除收藏按钮
2020/07/23 Javascript
js实现微信聊天效果
2020/08/09 Javascript
python绘制简单彩虹图
2018/11/19 Python
python 实现一次性在文件中写入多行的方法
2019/01/28 Python
python修改字典键(key)的方法
2019/08/05 Python
python中的Elasticsearch操作汇总
2019/10/30 Python
TensorFlow2.1.0最新版本安装详细教程
2020/04/08 Python
提高python代码运行效率的一些建议
2020/09/29 Python
python解包概念及实例
2021/02/17 Python
使用CSS Grid布局实现网格的流动
2014/12/30 HTML / CSS
解决H5的a标签的download属性下载service上的文件出现跨域问题
2019/07/16 HTML / CSS
菲律宾领先的在线时尚商店:Zalora菲律宾
2018/02/08 全球购物
Intimissimi德国网上商店:意大利知名内衣品牌
2018/04/03 全球购物
英国奢侈品概念店:Base Blu
2019/05/16 全球购物
Linux面试题LINUX系统类
2015/11/25 面试题
js正则匹配markdown里的图片标签的实现
2021/03/24 Javascript
数字化校园建设方案
2014/05/03 职场文书
如何签定毕业生就业协议书
2014/09/28 职场文书
2015年小学语文工作总结
2015/05/25 职场文书
HTML+css盒子模型案例(圆,半圆等)“border-radius” 简单易上手
2021/05/10 HTML / CSS
Win11自动黑屏怎么办 Win11自动黑屏设置教程
2022/07/15 数码科技