3

有很多关于如何将 indexOf 实现放入 Array 原型以便它在 Internet Explorer 下工作的解决方案,但是我偶然发现了一个问题,到目前为止我似乎在任何地方都没有解决这个问题。

使用在 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 函数代码的附加警报。

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

4

3 回答 3

5

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

对于使用数组(以及通常任何类似数组的对象),我不建议使用该for...in语句。

为什么 ?

  • for...in语句旨在枚举对象属性。
  • 正如您所注意到的,该for...in语句爬上了原型链。
  • 迭代的顺序可以是任意的,遍历一个数组可能不会访问数字顺序中的元素。

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

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

也可以看看:

于 2010-05-19T19:37:30.057 回答
3

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

for..inJavaScript 中的构造不像 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检查键是否未被继承并属于实际对象。这样只有需要的值通过。

于 2010-05-19T19:34:12.783 回答
0

您可以尝试添加:

for (j in i) {
    if (i.hasOwnProperty(j)) { 
        alert(j); 
    }
}
于 2010-05-19T19:28:38.207 回答