Internet Explorer的数组indexOf实现

时间:2010-05-19 19:24:44

标签: javascript internet-explorer arrays indexof

有很多关于如何将indexOf实现转换为Array原型的解决方案,以便它可以在Internet Explorer下运行,但是我偶然发现了一个似乎无法在我看到的任何地方解决的问题

使用非常好的implementation at MDC同意,我现在有以下代码存在问题:

// indexOf support for IE (from MDC)
if (!Array.prototype.indexOf)
{
    Array.prototype.indexOf = function(elt /*, from*/)   
    {
        var len = this.length >>> 0;

        var from = Number(arguments[1]) || 0;
        from = (from < 0) ? Math.ceil(from) : Math.floor(from);
        if (from < 0)
            from += len;

        for (; from < len; from++)
        {
            if (from in this && this[from] === elt)  
                return from;
        }
        return -1;
    };
}

var i = [1,2,3,4];

for (j in i)
{
    alert(i[j]);
}

我希望收到4个警报,每个警报包含一个数组元素。 在Firefox和Chrome中,这正是我所看到的,但是在IE8中,我得到一个包含indexOf功能代码的附加警报。

可以做些什么来避免这种情况?

3 个答案:

答案 0 :(得分:5)

这是因为在IE中,由于该方法不存在,因此它被添加到Array.prototype,并且它仍然是可枚举的。

对于使用Arrays进行woking(通常是任何类似数组的对象),我不建议使用for...in语句。

为什么?

  • for...in语句旨在枚举对象属性。
  • 您注意到for...in语句会抓取原型链。
  • 迭代的顺序可以是任意的,迭代数组可能无法按数字顺序访问元素。

最简单的方法,简单的for循环:

for (var j = 0; j < i.length; j++) {
    alert(i[j]);
}

另见:

答案 1 :(得分:3)

这是因为您编辑了Array.prototype,因此创建的任何数组都继承了“in”命令可以看到的自定义VISIBLE方法indexOf

JavaScript中的

for..in构造不像PHP的foreach那样 - 它不仅迭代数组中的所有项,而且还迭代数组OBJECT可能具有的所有方法和属性(JavaScript中的数组)实际上是“伪装”的对象)。本地方法对于for..in构造是不可见的,但所有自定义添加都不是。

在您的示例中,任何数组都如下所示:

Array:
- [0] value
- [1] value
- [2] value
- ..
- [N] value
- [IndexOf] value

要避免使用非需要的继承方法和属性,可以使用方法hasOwnProperty()

for (j in j){
    if(i.hasOwnProperty(j){
        alert(i[j])
    }
}

hasOwnProperty检查密钥是否未被继承并属于实际对象。这样只会传递所需的值。

答案 2 :(得分:0)

您可以尝试添加:

for (j in i) {
    if (i.hasOwnProperty(j)) { 
        alert(j); 
    }
}