0

我已经为 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");

4

3 回答 3

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循环。

于 2012-09-19T13:50:59.730 回答
0

您的问题是您的新indexOf()方法被标记为“可枚举”。不幸的是,在 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 循环的数组。

于 2012-09-19T13:49:21.593 回答
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

这是一个小提琴,在 IE8 中检查,它工作得很好

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

于 2012-09-19T13:41:00.660 回答