IE에서 indexOf()가 작동하지 않는 이유
구버전 인터넷 익스플로러(Internet Explorer 8 이하)는 ECMAScript 5 표준에 포함된 Array.indexOf() 메서드를 지원하지 않습니다. 그 결과 최신 브라우저에서는 정상적으로 동작하던 코드가 IE에서는 오류를 일으키거나 예상과 다른 결과를 반환하게 됩니다.
이러한 호환성 문제를 해결하는 가장 간단한 방법 중 하나는 jQuery에서 제공하는 jQuery.inArray() 메서드를 활용하는 것입니다.
jQuery.inArray( value, array [, fromIndex ] )
jQuery.inArray()는 배열 안에서 특정 값의 인덱스를 찾아주며, 값을 찾지 못하면 -1을 반환합니다. 이는 Array.indexOf()와 거의 동일한 방식으로 동작하기 때문에 IE 환경에서도 안정적으로 사용할 수 있습니다.
조건부 주석으로 IE에만 폴리필 적용하기
IE 전용으로 작동하는 조건부 주석(Conditional Comment)을 사용하면 해당 버전 이하의 IE 브라우저에서만 특정 스크립트를 실행하도록 할 수 있습니다. 다음과 같이 작성합니다.
<!--[if lte IE 10]>
lte IE 10은 "Internet Explorer 10 이하 버전"을 의미합니다. 즉, IE10 이하 브라우저에서만 내부 코드가 실행됩니다.
Array.prototype.indexOf 폴리필 작성하기
조건부 주석 안에서 Array.prototype에 indexOf가 존재하는지 확인한 후, 존재하지 않을 경우 직접 구현한 코드를 추가하면 됩니다.
<!--[if lte IE 10]>
<script>
if (!Array.prototype.indexOf) {
// add code
}
</script>
<![endif]-->실제 폴리필 코드는 다음과 같이 작성할 수 있습니다.
<script>
if (!Array.prototype.indexOf) {
Array.prototype.indexOf = function(searchElement, fromIndex) {
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 (n >= len) return -1;
var 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;
};
}
</script>이렇게 하면 최신 브라우저에는 영향을 주지 않으면서, 구버전 IE에서만 indexOf() 기능을 보완해 줄 수 있습니다. 참고로 조건부 주석은 IE9까지 공식 지원되었으며, IE10부터는 지원되지 않으므로 실무에서는 IE9 이하 대응 용도로 사용하는 것이 일반적입니다.