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

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>

(0)

相关推荐

  • Notice: Trying to get property of non-object problem(PHP)解决办法

    我这里实际是调用了一个zend的数据库访问的方法,使用了fetchAll方法,但由于数据库中没有该记录,所以返回的对象是null,所以我就判断对象是否为null: 复制代码 代码如下: if($obj==null){ ... } 这么写的结果,就是产生了上面那个notice,也真是奇怪,对象为null,竟然不能访问了? 翻查资料后,发现,判断是否为null,需要这么判断: 复制代码 代码如下: if (isset($obj)) { echo "This var is set set so I w

  • js报错 Object doesn't support this property or method的原因分析

    js报错: Object doesn't support this property or method 问题原因: 1:js代码用了javascript关键字 2:方法名和表单或者div form名冲突 3.button中有name="submit" 4.上传图片时提示:Object doesn't support this property or method 原因:服务器上安装的AspJpeg的版本低于1.4版. 解决方法:安装1.4或以上版本的AspJpeg组件. 我也遇到这个

  • js截取函数(indexOf,join等)

    函数:indexOf() 功能:返回字符串中匹配子串的第一个字符的下标 复制代码 代码如下: var myString="JavaScript"; var w=myString.indexOf("v");w will be 2 var x=myString.indexOf("S");x will be 4 var y=myString.indexOf("Script");y will also be 4 var z=myStr

  • javascript 判断字符串是否包含某字符串及indexOf使用示例

    通过判断指定目录实现广告的显示 复制代码 代码如下: if(location.href.indexOf("http://www.jb51.net/codes/")>-1){ alert('ok'); } 复制代码 代码如下: var Cts = "bblText"; if(Cts.indexOf("Text") >= 0 ) { alert('Cts中包含Text字符串'); } indexOf用法: 返回 String 对象内第一次

  • js中indexof的用法详细解析

    String.IndexOf 方法 (Char, [startIndex], [count]) 报告指定字符在此实例中的第一个匹配项的索引.搜索从指定字符位置开始,并检查指定数量的字符位置. 参数 value 要查找的 Unicode 字符. 对 value 的搜索区分大小写. startIndex(Int32) 可选项,搜索起始位置.不设置则从0开始. count(Int32) 可选项,要检查的字符位置数. 返回值 如果找到该字符,则为 value 的索引位置:否则如果未找到,则为 -1. I

  • js indexOf()定义和用法

    返回 String 对象内第一次出现子字符串的字符位置. strObj.indexOf(subString[, startIndex]) 参数 strObj 必选项.String 对象或文字. subString 必选项.要在 String 对象中查找的子字符串. starIndex 可选项.该整数值指出在 String 对象内开始查找的索引.如果省略,则从字符串的开始处查找. 说明 indexOf 方法返回一个整数值,指出 String 对象内子字符串的开始位置.如果没有找到子字符串,则返回

  • js中substr,substring,indexOf,lastIndexOf的用法小结

    js中substr,substring,indexOf,lastIndexOf等的用法 1.substrsubstr(start,length)表示从start位置开始,截取length长度的字符串. var src="images/off_1.png";alert(src.substr(7,3)); 弹出值为:off 2.substringsubstring(start,end)表示从start到end之间的字符串,包括start位置的字符但是不包括end位置的字符. var src

  • jQuery ajax BUG:object doesn't support this property or method

    问题:jQuery控件的一个BUG 使用$.ajax时出现的错误,IE7下才会出错,IE6,IE8都正常.错误提示如下图: 官方论坛上的说明: http://forum.jquery.com/topic/object-doesn-t-support-this-property-or-method-from-jquery-1-4-1-in-ie7-onlyhttp://dev.jquery.com/ticket/6498http://dev.jquery.com/ticket/6314解决方案:修

  • JavaScript从数组的indexOf()深入之Object的Property机制

    在JavaScript中,数组可以使用Array构造函数来创建,或使用[]快速创建,这也是首选的方法.数组是继承自Object的原型,并且他对typeof没有特殊的返回值,他只返回'object'. js中,可以说万物皆对象(object),一个数组也是一个对象(array). 很多对象都有很多很方便的方法 比如数组的push,concat,slice等等,但是如果一些对象,它没有实现这些方法,我们还是想使用这些功能.那该怎么办呢? 1.很多方法都提供了非常高效的实现, 我们可以仿照它们的实现.

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

    Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了.但是这个自定义的indexOf在对数组进行遍历的时候却出现了问题. Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了. 复制代码 代码如下

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

    Array没有indexOf方法,这样在一个数组中查找某个元素的索引时比较麻烦,为了调用方便,于是通过prototype原型扩展了Array.prototype.indexOf(),这样用起来就比较方便了.但是这个自定义的indexOf在对数组进行遍历的时候却出现了问题. 复制代码 代码如下: Array.prototype.indexOf = function(item) {  for (var i = 0; i < this.length; i++) {  if (this[i] == it

  • js使用Array.prototype.sort()对数组对象排序的方法

    本文实例讲述了js使用Array.prototype.sort()对数组对象排序的方法.分享给大家供大家参考.具体分析如下: 在讲对数组对象进行排序时,我们先来简单的了解一下Array.prototype.sort().sort方法接受一个参数--Function,function会提供两个参数,分别是两个进行比较的元素,如果元素是String类型则通过Unicode code进行比较,如果是Number类型则比较值的大小.如果比较的函数中返回1则两个元素交换位置,0和-1不交换位置.先看一个例

  • JS扩展String.prototype.format字符串拼接的功能

    1.题外话,有关概念理解:String.prototype 属性表示 String原型对象.所有 String 的实例都继承自 String.prototype. 任何String.prototype上的改变都会影响到所有的 String 实例. 2.上正文,js扩展String.prototype.format字符串拼接的功能,首先是基础功能的改造: String.prototype.format = function(){ if(arguments.length==0){ return th

  • js下通过prototype扩展实现indexOf的代码

    复制代码 代码如下: <script type="text/javascript"> Array.prototype.indexOf = function (str) { for (var i = 0; i < this.length; i++) { if (str == this[i]) { return i; } } return -1; } </script>

  • 详解JS中Array对象扩展与String对象扩展

    废话不多说了,直接给大家上array对象扩展代码了,具体代码如下所示: /** * Created by laixiangran on 2016/01/07. * Array扩展 */ (function() { // 遍历数组 if (typeof Array.prototype.forEach != "function") { Array.prototype.forEach = function (fn, context) { for (var i = 0; i < this

  • 5个数组Array方法: indexOf、filter、forEach、map、reduce使用实例

    ECMAScript5标准发布于2009年12月3日,它带来了一些新的,改善现有的Array数组操作的方法.然而,这些新奇的数组方法并没有真正流行起来的,因为当时市场上缺乏支持ES5的浏览器. Array "Extras" 没有人怀疑这些方法的实用性,但写polyfill(PS:兼容旧版浏览器的插件)对他们来说是不值得的.它把"必须实现"变成了"最好实现".有人居然将这些数组方法称之为Array "Extras".哎! 但是,

  • 简单谈谈JS数组中的indexOf方法

    前言 相信说到 indexOf 大家并不陌生,判断字符串是否包涵子字符串时特别常用,正则不熟练同学的利器.这篇文章就最近遇到的一个问题,用实例再说说说indexOf方法.本文是小知识点积累,不作为深入讨论的话题,因此这里没有解释indexOf()的第二个参数,相信大家都知道第二个参数的作用. String 类型的使用 温习一下大家熟知的字符串用法,举个 let str = 'orange'; str.indexOf('o'); //0 str.indexOf('n'); //3 str.inde

  • Array.prototype.slice 使用扩展

    除了正常用法,slice 经常用来将 array-like 对象转换为 true array. 名词解释:array-like object – 拥有 length 属性的对象,比如 { 0: 'foo', length: 1 }, 甚至 { length: 'bar' }. 最常见的 array-like 对象是 arguments 和 NodeList. 查看 V8 引擎 array.js 的源码,可以将 slice 的内部实现简化为: 复制代码 代码如下: function slice(s

  • JS数组降维的实现Array.prototype.concat.apply([], arr)

    把多维数组(尤其是二维数组)转化为一维数组是业务开发中的常用逻辑,最近跟着黄轶老师学习Vue2.6.1.1版本源码时,看到源码对二维数组降维的代码,所以这里来写一篇,记录一下,加强印象 二维数组降为一维数组 循环降维 let children = [1, 2, 3, [4, 5, 6], 7, 8, [9, 10]]; function simpleNormalizeChildren(children) { let reduce = []; for (let i = 0; i < childre

随机推荐