为啥 indexOf 在数组 IE8 上不起作用?

Posted

技术标签:

【中文标题】为啥 indexOf 在数组 IE8 上不起作用?【英文标题】:Why doesn't indexOf work on an array IE8?为什么 indexOf 在数组 IE8 上不起作用? 【发布时间】:2011-04-07 10:47:21 【问题描述】:

以下功能在 Opera、Firefox 和 Chrome 上运行良好。但是,在 IE8 中,if ( allowed.indexOf(ext[1]) == -1) 部分会失败。

有人知道为什么吗?有什么明显的错误吗?

function CheckMe() 
    var allowed = new Array('docx','xls','xlsx', 'mp3', 'mp4', '3gp', 'sis', 'sisx', 'mp3', 'wav', 'mid', 'amr', 'jpg', 'gif', 'png', 'jpeg', 'txt', 'pdf', 'doc', 'rtf', 'thm', 'rar', 'zip', 'htm', 'html', 'css', 'swf', 'jar', 'nth', 'aac', 'cab', 'wgz');
    var fileinput=document.getElementById('f');
    var ext = fileinput.value.toLowerCase().split('.');
    if ( allowed.indexOf(ext[1]) == -1) 
    
        document.getElementById('uploadsec').innerHTML = document.getElementById('uploadsec').innerHTML;
        alert('This file type is not allowed!');
    

【问题讨论】:

好问题,好答案。谢谢你给了我我需要的东西。 【参考方案1】:

IE9之前的IE版本没有数组的.indexOf()函数,要定义the exact spec version,在尝试使用之前运行它:

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;
  ;

这是版本from MDN,用于Firefox/SpiderMonkey。在其他情况下,例如IE,它会添加.indexOf()以防它丢失......此时基本上是IE8或以下。

【讨论】:

请注意,如果您(或您使用的库)使用 for/in 语法来枚举数组(例如 for(idx in arrayname)stmt;),该方法也将被枚举。这是因为内置属性不是由 for/in 枚举的,而是由用户定义的。 @Mike - 这是一个不同的问题......你不应该使用for...in 循环来迭代一个数组,它应该用于枚举 仅限。 @Mike - 你迭代一个数组有更多的原因......比如让你的结果在浏览器中以正确的顺序排列。在数组上使用for..in 只会导致问题,这不仅仅是一种约定……它是非预期的用法和不正确的用法。顺序和键都没有完全指定,它们依赖于实现...例如 IE 将按照它们添加的顺序枚举数组项,而不是按它们的顺序指数。但是,您可以按索引正确迭代 这说明了枚举元素和使用索引进行迭代之间的区别。这就是为什么我们有这两个概念。您可以枚举链表中的值,也可以爬取链表并从一个到下一个返回值。一个是数学概念,一个是程序指令。 @Pointy 是的!并且由于许多搜索“为什么 indexOf 不能在数组 IE8 上工作?” WRT 到 js 的复杂程度可能较低,指出这一点作为答案的必然结果可能会有所帮助。如果每个人都已经对规范和实现之间的差异有深入的了解,那么这样的线程就不会存在。 @Nick您对正确性做出了强有力的假设。有许多操作的顺序无关紧要(例如,设置差异。)此外,原始评论没有提到索引序列中的枚举,只是 for/in 包括用户 def fn 的。【参考方案2】:

如果您使用的是 jQuery,则可以改用 $.inArray()。

【讨论】:

我同意这更有用。这是使用 JQuery 的主要原因之一 - 它在缓解跨浏览器不兼容方面做了很多工作。【参考方案3】:

如果您正在使用 jQuery 并希望继续使用 indexOf 而不必担心兼容性问题,您可以这样做:

if (!Array.prototype.indexOf) 
    Array.prototype.indexOf = function(val) 
        return jQuery.inArray(val, this);
    ;

当您想继续使用 indexOf 但在它不可用时提供备用方案时,这很有帮助。

【讨论】:

是的,可能是因为他没有包含 jQuery ¯_(ツ)_/¯ 是合法的语法。【参考方案4】:

要获得真正彻底的解释和解决方法,不仅针对 indexOf,还针对 IE 中缺少的其他数组函数,请查看 *** 问题 Fixing javascript Array functions in Internet Explorer (indexOf, forEach, etc.)

【讨论】:

【参考方案5】:

如果你想使用它,请小心使用 $.inArray。 我刚刚发现 $.inArray 仅适用于“Array”,而不适用于 String。 这就是为什么这个功能在 IE8 中不起作用的原因!

jQuery API 造成混乱

$.inArray() 方法类似于 JavaScript 原生的 .indexOf() 方法,因为它在找不到匹配项时返回 -1。如果 数组中的第一个元素匹配值,$.inArray() 返回 0

--> 他们不应该说“相似”。由于 indexOf 也支持 "String"!

【讨论】:

它叫做inArray。这似乎非常明确地仅适用于数组。这就是为什么它“相似”而不是“相同”。 好消息。有趣的事实是,字符串对象中的indexOf 在 IE 中完全可以找到,而数组原型中的indexOf 在 IE 您将它绑定到数组原型,因此它不会影响字符串。【参考方案6】:

问题

IEindexOf() 方法。


解决办法

如果你在IEindexOf,你应该考虑使用下面的polyfill,也就是recommended at the MDN:

if (!Array.prototype.indexOf) 
    Array.prototype.indexOf = function(searchElement, fromIndex) 
        var k;
        if (this == null) 
            throw new TypeError('"this" is null or not defined');
        
        var o = Object(this);
        var len = o.length >>> 0;
        if (len === 0) 
            return -1;
        
        var n = +fromIndex || 0;
        if (Math.abs(n) === Infinity) 
            n = 0;
        
        if (n >= len) 
            return -1;
        
        k = Math.max(n >= 0 ? n : len - Math.abs(n), 0);
        while (k < len) 
            if (k in o && o[k] === searchElement) 
                return k;
            
            k++;
        
        return -1;
    ;

缩小:

Array.prototype.indexOf||(Array.prototype.indexOf=function(r,t)var n;if(null==this)throw new TypeError('"this" is null or not defined');var e=Object(this),i=e.length>>>0;if(0===i)return-1;var a=+t||0;if(Math.abs(a)===1/0&&(a=0),a>=i)return-1;for(n=Math.max(a>=0?a:i-Math.abs(a),0);i>n;)if(n in e&&e[n]===r)return n;n++return-1);

【讨论】:

【参考方案7】:

如果函数不存在,你可以用它来替换:

<script>
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;
    ;

</script>

【讨论】:

以上是关于为啥 indexOf 在数组 IE8 上不起作用?的主要内容,如果未能解决你的问题,请参考以下文章

Dojo 功能在 IE8 上不起作用

jqgrid在IE8上不起作用

摘要身份验证在 IE8、Firefox 和 Chrome 上不起作用

Less Css 在 IE8 和 IE7 上不起作用

A4J reRender 在 IE9 上不起作用 [在 IE8 上工作]

为啥 Bootstrap 3 导航栏下拉菜单在 IE8 中不起作用?