Почему 'for(var item in list)' с массивами считается плохой практикой в JavaScript?
Имеется простой нумерованный индексированный массив:
var list = ['Foo', 'Bar', 'Baz'];
Много раз я замечал это, когда кто-то предлагает перебирать переменные в массиве следующим образом:
for(var item in list) { ... }
... почти наверняка кто-то говорит, что это плохая практика, и предлагает альтернативный подход:
var count = list.length;
for(var i = 0; i < count; i++) {
var item = list[i];
...
}
В чем причина не использовать более простую версию выше и использовать вместо нее второй пример?
5 ответов
Во-первых, порядок цикла не определен для for...in
цикл, поэтому нет гарантии, что свойства будут повторяться в нужном вам порядке.
Во-вторых, for...in
перебирает все перечисляемые свойства объекта, в том числе наследуемые от его прототипа. В случае массивов это может повлиять на вас, если ваш код или любая библиотека, включенная в вашу страницу, дополнили прототип Array
что может быть действительно полезным:
Array.prototype.remove = function(val) {
// Irrelevant implementation details
};
var a = ["a", "b", "c"];
for (var i in a) {
console.log(i);
}
// Logs 0, 1, 2, "remove" (though not necessarily in that order)
Скорость?
for(..;..;..)
петля оказалась в 36 раз быстрее for .. in
когда я проверял это здесь.
for ... in ...
не возвращает элементы списка, а перечисляет свойства массива.
Только по этой причине он не может служить заменой for (i=0; i<arr.length; i++)
петля.
Подходящая альтернатива for ... of ...
построить. Он перечисляет значения повторяемого объекта, такого как массив. Вы можете прочитать больше об этом в MDN Web Docs: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/for...of
Он поддерживается соответствующими современными браузерами (Internet Explorer не учитывается, его заменяет Microsoft Edge). Если вы можете позволить себе не поддерживать старые браузеры, это, вероятно, путь. Вы можете проверить удобную таблицу поддержки браузера в конце вышеупомянутой страницы MDN, чтобы увидеть, какие версии браузера на самом деле позволяют for ... of ...
использование.
Если вы используете для / в, как это, item
перечисляет через строковые значения "0", "1", ..., а не фактические объекты в списке. Таким образом, "элемент" в первом фрагменте больше похож на i
во втором фрагменте, а не item
, Кроме того, строковые значения перечисляются там, где вы ожидаете чисел. И вы попали в беду, когда вы свойства в список, как array.ID = "a123"
, как они и будут перечислены.
Но с этими недостатками я все еще думаю, что синтаксис очень полезен, если ваша команда знает, что он делает.
Добавлять list.foo = bar;
и попробуйте использовать простой for
, Если вы не используете некоторые библиотеки (например, prototypeJs) и не добавляете какие-либо новые свойства в объект массива - вы можете использовать простое for-Statement.