Почему' 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, как это,
item
перечисляет через строковые значения "0", "1",..., так что не фактические объекты в списке. Таким образом, "элемент" в первом фрагменте больше похож наi
во втором фрагменте,а неitem
. Кроме того, строковые значения перечисляются там, где вы ожидаете числа. И вы попадаете в беду, когда вы свойства в список, какarray.ID = "a123"
, так как они также будут перечислены.но с этими недостатками, я все еще думаю, что синтаксис очень полезен, если ваша команда знает, что она делает.
добавить
list.foo = bar;
и попробуйте использовать простойfor
. Если вы не используете некоторые библиотеки (например, prototypeJs) и не добавляете никаких новых свойств к объекту array - вы можете использовать простой оператор for.
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 ...
использование.