배열 IE8에서 indexOf가 작동하지 않는 이유는 무엇입니까?


294

아래 기능은 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!');
    }
}

5
좋은 질문, 좋은 답변입니다. 필요한 것을 정확히 제공해 주셔서 감사합니다.
Hardwareguy

답변:


488

IE9 이전의 IE 버전에는 .indexOf()Array에 대한 기능 이 없으므로 정확한 스펙 버전 을 정의 하려면 사용하기 전에 이것을 실행하십시오.

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

Firefox / SpiderMonkey에서 사용되는 MDN 버전 입니다 . IE와 같은 다른 경우에는 .indexOf()누락 된 경우 추가 됩니다 ... 기본적으로 IE8 이하입니다.


2
주의 사항 (또는 사용하는 라이브러리)이 for / in 구문을 사용하여 배열 (예 : for (idx in arrayname) stmt;)을 열거하면이 방법도 열거된다는주의 사항에 유의하십시오. 내장 속성은 for / in으로 열거되지 않지만 사용자 정의 속성은 열거되기 때문입니다.
스페인 열차

5
@ Mike-그것은 다른 문제입니다 ... for...in루프를 사용 하여 배열 을 반복 해서는 안되며 열거 에만 사용해야합니다 .
Nick Craver

3
@Mike-브라우저에서 올바른 순서로 결과를 얻는 것과 같이 더 많은 이유로 배열을 반복합니다. for..in배열에서 사용 하면 문제가 발생할 수 있으며 이는 단지 관습이 아닙니다. 의도하지 않은 사용법과 잘못된 것입니다. 순서와 키는 완전히 지정되지 않았으며 구현에 따라 다릅니다. 예를 들어 IE는 색인이 아닌 추가 된 순서대로 배열 항목을 열거 합니다 . 그러나 인덱스별로 액세스하여 올바르게 반복 할 수 있습니다 .
Nick Craver

1
그리고 그것은 요소를 열거하고 인덱스를 사용하여 반복하는 것의 차이점을 보여줍니다. 그렇기 때문에 두 가지 개념이 모두 있습니다. 연결된 목록의 값을 열거하거나 연결된 목록을 크롤링하여 값을 하나씩 반환 할 수 있습니다. 하나는 수학적 개념이고, 하나는 절차 적 명령입니다.
jcolebrand

1
@Pointy 네! 그리고 "왜 IE8에서 indexOf가 작동하지 않습니까?" js에 대한 WRT의 정교함이 낮을 수 있습니다. 대답에 대한 추론으로 지적하면 도움이 될 수 있습니다. 모든 사람이 이미 사양과 구현 간의 차이점에 대해 깊이 이해했다면 이러한 스레드는 존재하지 않을 것입니다. @Nick 정확성에 대해 강력한 가정을합니다. 순서가 중요하지 않은 많은 연산이 있습니다 (예 : 차이 설정).
스페인 기차

152

jQuery를 사용하는 경우 $ .inArray ()를 대신 사용할 수 있습니다 .


7
이것이 더 유용하다는 데 동의합니다. 이것이 JQuery를 사용하는 주된 이유 중 하나입니다. 브라우저 간 비 호환성을 완화하는 데 많은 도움이됩니다.
cw24

17

당신이 사용하는 경우 jQuery를 하고 호환성 문제에 대한 걱정없이 같이 IndexOf를 계속 사용하려면, 당신은이 작업을 수행 할 수 있습니다 :

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

이 기능은 계속 사용하고 indexOf싶지만 사용할 수없는 경우 대체 기능을 제공 할 때 유용 합니다.


예, 아마도 그는 jQuery를 포함하지 않았기 때문에 ¯_ (ツ) _ / ¯ 그것은 유효한 구문입니다.


5

사용하려면 $ .inArray에주의하십시오. 방금 $ .inArray가 String이 아니라 "Array"에서만 작동한다는 것을 알았습니다. 이것이 IE8에서이 기능이 작동하지 않는 이유입니다!

jQuery API로 혼란

$ .inArray () 메서드는 일치하는 것을 찾지 못하면 -1을 반환한다는 점에서 JavaScript의 기본 .indexOf () 메서드와 유사합니다. 배열 내의 첫 번째 요소가 value와 일치하면 $ .inArray ()는 0을 반환합니다.

-> "Similar"라고 말해서는 안됩니다. indexOf를 지원하기 때문에 "String"도!


16
이라고 inArray합니다. 배열에만 적용하는 것이 확실합니다. 그렇기 때문에 "유사한"것이 아니라 "유사한"이유입니다.
tandrewnichols

좋은 메모입니다. 재미있는 사실은 indexOf배열 개체 indexOf에서 IE <= 8에서 찾을 수 없지만 IE에서 String 개체가 완전히 발견된다는 것입니다.
adi518

배열 프로토 타입에 바인딩하므로 문자열에 영향을 미치지 않습니다.
kagronick

3

문제

IE <= 8에는 단순히 indexOf()배열에 대한 메소드 가 없습니다 .


해결책

indexOfIE <= 8 이 필요한 경우 MDN에서 권장 되는 다음 polyfill 사용을 고려해야 합니다 .

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

1

존재하지 않는 경우이를 사용하여 함수를 대체 할 수 있습니다.

<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>
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.