为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] == 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)

相关推荐

  • javascript当中的代码嗅探扩展原生对象和原型(prototype)

    注:翻译之中有什么不恰当的地方,欢迎大家指正,祝大家双节快乐! 如果不是有特殊需要而去扩展原生对象和原型(prototype)的做法是不好的 复制代码 代码如下: //不要这样做 Array.prototype.map = function() { // 一些代码 }; 除非这样做是值得的,例如,向一些旧的浏览器中添加一些ECMAScript5中的方法. 在这种情况下,我们一般这样做: 复制代码 代码如下: if (!Array.prototype.map) { Array.prototype.

  • 基于prototype扩展的JavaScript常用函数库

    复制代码 代码如下: /** 2 * 检索数组元素(原型扩展或重载) 3 * @param {o} 被检索的元素值 4 * @type int 5 * @returns 元素索引 6 */ 7 Array.prototype.contains = function(o) { 8 var index = -1; 9 for(var i=0;i<this.length;i++){if(this[i]==o){index = i;break;}} return index; } /** * 日期格式化

  • js实现prototype扩展的方法(字符串,日期,数组扩展)

    本文实例讲述了js实现prototype扩展的方法.分享给大家供大家参考,具体如下: String.prototype.isEmpty = function () { return !(/.?[^/s ]+/.test(this)); } //检测字符串是否为空 // 替换字符 String.prototype.reserve = function(type) { if (type == 'int') return this.replace(/^/d/g, ''); // 替换字符串中除了数字以

  • javascript Prototype 对象扩展

    Javascript当然也不例外,可是关于对象的引用问题,你考虑过么?通常的做法是一系列对象共享类的方法,而不是为每个对象复制一份函数.下面看看为每个对象复制一份函数的做法. 复制代码 代码如下: var myobject=function(param1,param2) { this.name=param1; this.age=param2; this.showmsg=function() { alert("name:"+this.name+"\n"+"a

  • 扩展javascript的Date方法实现代码(prototype)

    最近项目的部分功能正在重构,前端也基本上推翻了原来的设计,在之前半年的积累上有了新的方案.这几天在做前端的重构和设计,遇到了一些问题.因为这个模块最主要的还是对时间的控制,大量的操作js的Date对象,可是js原生的Date方法太少了,操作起来太不方便.于是打算扩展下Date的prototype. 长期从事C#的开发,被C#影响着我的思维.C#中DateTime的操作就很方便,于是就参考它对js的Date做了扩展. 复制代码 代码如下: //将指定的毫秒数加到此实例的值上 Date.protot

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

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

  • 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>

  • javascript中的prototype属性使用说明(函数功能扩展)

    这是一个比较特殊的属性,Javascript中的继承一般都依赖这属性实现. 在Javascript中,一切都是对象,字符串是对象,数组是对象,变量是对象,函数也是对象,所以才会允许['a','b','c'].push('d');这样的操作存在.类本身也是一个对象,也可以定义属性和方法: 复制代码 代码如下: function Test(){}; Test.str = 'str'; Test.fun = function(){return 'fun';}; var r1 = Test.str; /

  • 为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获取填报扩展单元格控件的值的解决办法

    1. 问题描述 填报预览时,我们想获取到某个控件的值相对来说较容易.但如果控件是扩展的,就只能获取到第一个值,无法根据扩展一行行获取对应的值. 例:本意是想获取到袁成洁,结果还是获取到第一个单元格值孙林. 2. 解决方法 我们可以通过js事件来获取对应行控件的值. 3. 示例 新建一个模板,添加数据集ds1:SELECT * FROM 销量 A1单元格设置下拉框控件,B1单元格设置按钮控件,下拉框控件是向下扩展的,模板设计如下图所示: 给B1单元格按钮控件添加一个JS点击事件: js代码如下:

  • JS定时检测任务任务完成后执行下一步的解决办法

    拿到一个需求,web前端调用一个脚本将数据写入ssdb,后从ssdb中查询并做展示.需要检测到脚本执行完毕后再做查询,于是有了如下简单的逻辑,感觉这个逻辑还比较实用,就做下记录~不废话,上代码. <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title></title> </head> <body

  • php安装扩展mysqli的实现步骤及报错解决办法

    php安装扩展mysqli的实现步骤及报错解决办法 terminal #cd php-5.3.6/ext/mysqli #/usr/local/webserver/php/bin/phpize #./configure --with-php-config=/usr/local/webserver/php/bin/php-config #make #make instal 报错: checking for MySQLi support... yes checking whether to enab

  • node.js报错:Cannot find module 'ejs'的解决办法

    发现问题 最近同事问了一个问题,他在用node.js的时候,发现node.js报错了,错误显示: Error: Cannot find module 'ejs' at Function.Module._resolveFilename (module.js:325:15) at Function.Module._load (module.js:276:25) at Module.require (module.js:353:17) at require (internal/module.js:12

  • vue.js iview打包上线后字体图标不显示解决办法

    在vue+cli项目中使用iview组件及icon图标,打包后icon不显示,解决办法: 1.在build文件夹下找到utils.js文件,把publicPath改为 ../../ if (options.extract) { return ExtractTextPlugin.extract({ publicPath:'../../', use: loaders, fallback: 'vue-style-loader' }) } else { return ['vue-style-loader

  • node.js报错:Cannot find module 'ejs'的解决办法

    发现问题 最近同事问了一个问题,他在用node.js的时候,发现node.js报错了,错误显示: Error: Cannot find module 'ejs' at Function.Module._resolveFilename (module.js:325:15) at Function.Module._load (module.js:276:25) at Module.require (module.js:353:17) at require (internal/module.js:12

随机推荐