Internet Explorer中的数组indexOf

时间:2012-09-19 13:26:53

标签: javascript arrays

我为Array indexOf定义了原型(以支持Internet Explorer中的数组indexOf)

if(!Array.prototype.indexOf){
    Array.prototype.indexOf = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
               return i;
            }
         }
         return -1;
     }
}

当我使用值[1,2,3]创建数组时,此indexOf代码段添加到数组中,如下所示

["1","2","3",function(obj){for(var i=0;i<this.length;i++){if(this[i]==obj){return i;}}return -1;}]

此问题仅在IE中发生。

任何人都可以帮我解决这个问题。提前谢谢。


我没有在任何地方使用for...in循环,为此我使用jQuery sortable toArray方法.sortable("toArray");

3 个答案:

答案 0 :(得分:1)

我假设您在某些时候使用for...in循环来迭代数组的元素。例如:

for (var elem in myArray) {
    //Do stuff...
}

for...in循环将枚举对象的所有可枚举属性,包括它从其原型链中的祖先继承的属性。您已经为Array原型添加了一个方法:

Array.prototype.indexOf = function(obj){ //...

此属性是可枚举的(您无法定义不可枚举的属性 - 请参阅Object.defineProperty - 在旧版本的IE中),因此for...in循环将包含此属性。

简单的解决方案是永远不要使用for...in循环迭代数组!改为使用普通的for循环。

答案 1 :(得分:0)

这很简单,你的数组现在包含4个元素,其中第四个是函数对象,你没有为数组对象定义一个新方法,更不用说所有数组对象了。只需将第一个代码段粘贴到脚本的最顶部,然后:

 var foo = [1,2,3];
 alert(foo.indexOf(2));//alerts 1

Array.prototype视为每个数组的模板。每当您尝试访问数组的某个属性或方法时,未定义,而不是抛出错误,JS将首先检查Array.prototype该对象是否没有该方法/属性。如果是这样,JS将使用该代码,并将其应用于最初调用它的数组。在上面的示例中,foo.indexOf(2)可能已写为Array.prototype.indexOf.apply(foo,[2]);。换句话说:JS自动将原型的功能应用到foo

您的“完整”代码应如下所示:

if(!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(obj)
    {
        for(var i=0; i<this.length; i++)
        {
            if(this[i] === obj)//preferable, use strict comparison
            {
                return i;
            }
        }
        return -1;
    };
}
var yourArray = [1,2,3,4,'4'];
alert(yourArray.indexOf(4));//alerts 3
alert(yourArray.indexOf('4'));//alerts 4 when using strict comparison, if not, alerts 3

Here's a fiddle ,在IE8中查看,并且工作正常

只需google 原型继承原型链在JS 等中扩充原型,阅读并感到困惑! ;)

答案 2 :(得分:0)

您的问题是您的新indexOf()方法已标记为&#34;可枚举。&#34;不幸的是,在IE7或非标准模式的IE8中没有解决这个问题。但是你可以通过使用一些ES5技巧来至少修补标准模式IE8的问题。修改你的代码看起来像这样,如果你处于IE8标准模式,它应该摆脱额外的元素:

(function () {
    var indexOfFn = function(obj){
        for(var i=0; i<this.length; i++){
            if(this[i]==obj){
               return i;
            }
         }
         return -1;
    };

    if(!Array.prototype.indexOf){
        if(typeof Object.defineProperty === "function") {
            Object.defineProperty(Array.prototype, "indexOf", {
                value: indexOfFn,
                enumerable: false
            });
        } else {
            Array.prototype.indexOf = indexOfFn;
        }
    }
}());

我知道这是罗嗦的,所以可能不值得努力。但它也可以保护您的JavaScript免受其他人的错误编码,他们最终可能会使用带有for-in循环的数组。