Поведение `for (var i in arr)` в IE8 после расширения Array.prototype

Недавно решил посмотреть, как дела у моего jQuery плагина в IE8. Я думаю, предсказать что было дальше не сложнее, чем предугадать, чем закончится классическая голливудская мелодрама – в скрипте обнаружились ошибки.

Из-за убогости консоли я долго думал в чём дело и столкнулся с необычным явлением. Как известно, IE8, как и все другие десктопные браузеры от Microsoft с момента своего появления является сильно устаревшим браузером. В частности, в нём нет ряда методов из Array.prototype, таких как весьма удобный и относительно часто используемый indexOf(obj). Естественно я знал это и позаботился, добавив к проекту небольшой скрипт missed.js, который кочует у меня из проекта в проект, разрешая проблему недостающего функционала в IE8. Этот скрипт – классическое решение, он содержит ряд объявлений вида:

if (!Array.prototype.indexOf) { 
    Array.prototype.indexOf = function(...) {...} 
}

Не знаю, почему я впервые наткнулся на ошибку только недавно, но в общем это был первый раз, когда я увидел, как после этого будет использоваться код вида for (var i in arr), в случае, когда arr – массив.

Оказывается (с одной стороны конечно же логично, но с другой это далеко не сразу приходит в голову), что в таком случае i принимает значение не только индексов элементов массива, но и забирает не родные методы из своего, т.е. Array прототайпа. Поэтому использование такой конструкции без дополнительных правок (например делать continue, если i не является числом) невозможно.

Обсудив это с коллегой я пришёл к выводу, что лучше для массивов всегда использовать код вида for (var i = 0; i < arr.length; i++).

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>