【问题标题】:Array indexOf implementation for Internet ExplorerInternet Explorer 的数组 indexOf 实现
【发布时间】:2010-05-19 19:24:43
【问题描述】:

有很多关于如何将 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 函数代码的附加警报。

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

【问题讨论】:

    标签: javascript internet-explorer arrays indexof


    【解决方案1】:

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

    为了使用数组(通常是任何类似数组的对象),我不推荐使用for...in 语句。

    为什么?

    • for...in 语句用于枚举对象属性。
    • 如您所见,for...in 语句会爬上原型链。
    • 迭代顺序可以是任意的,对数组进行迭代可能不会访问数字顺序中的元素。

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

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

    另见:

    【讨论】:

    • 感谢您的信息。我只是希望 IE 能处理像 FF 和 Chrome 这样的东西。并且将 for...in 重写为 for 循环并不是一个真正的选择,遗留代码可能会很痛苦。
    【解决方案2】:

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

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

    【讨论】:

    • 约定是在对象(枚举)上使用for..in,在数组(迭代)上使用普通的for。查看 CMS 的答案
    • for..in 确实不是最适合迭代数组的结构,尤其是考虑到迭代的​​顺序无法保证但有时确实到位
    • 感谢您的信息。我只是希望 IE 能处理像 FF 和 Chrome 这样的东西。并且将 for...in 重写为 for 循环并不是一个真正的选择,遗留代码可能会很痛苦。
    【解决方案3】:

    你可以尝试添加:

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

    【讨论】:

      猜你喜欢
      • 2010-12-17
      • 2012-04-21
      • 1970-01-01
      • 1970-01-01
      • 2010-09-15
      • 1970-01-01
      • 2012-10-06
      • 2015-04-17
      相关资源
      最近更新 更多