Почему использование «for ... in» с итерацией массива - плохая идея? - PullRequest
1691 голосов
/ 01 февраля 2009

Мне сказали не использовать for...in с массивами в JavaScript. Почему нет?

Ответы [ 26 ]

6 голосов
/ 24 ноября 2010

Вы должны использовать for(var x in y) только в списках свойств, а не в объектах (как описано выше).

5 голосов
/ 17 сентября 2017

Использование цикла for...in для массива не является неправильным, хотя я могу догадаться, почему кто-то сказал вам, что:

1.) Уже существует функция или метод более высокого порядка, который имеет эту цель для массива, но имеет больше функциональности и более тонкий синтаксис, называемый 'forEach': Array.prototype.forEach(function(element, index, array) {} );

2.) Массивы всегда имеют длину, но for...in и forEach не выполняют функцию для любого значения, равного 'undefined', только для индексов, для которых определено значение. Таким образом, если вы присваиваете только одно значение, эти циклы будут выполнять функцию только один раз, но, поскольку массив перечисляется, он всегда будет иметь длину до самого высокого индекса, который имеет определенное значение, но эта длина может остаться незамеченной при использовании этих значений. петли.

3.) Стандарт для цикла будет выполнять функцию столько раз, сколько вы определили в параметрах, и поскольку массив нумеруется, имеет смысл определить, сколько раз вы хотите выполнить функцию. В отличие от других циклов, цикл for может затем выполнять функцию для каждого индекса в массиве, независимо от того, определено это значение или нет.

По сути, вы можете использовать любой цикл, но вы должны точно помнить, как они работают. Понять условия, при которых повторяются различные циклы, их отдельные функции и понять, что они будут более или менее подходящими для различных сценариев.

Кроме того, лучше использовать метод forEach, чем цикл for...in в целом, потому что он проще для написания и обладает большей функциональностью, поэтому вы можете захотеть использовать только привычку используя этот метод и стандарт для, но ваш вызов.

См. Ниже, что первые два цикла выполняют операторы console.log только один раз, в то время как стандарт цикла выполняет функцию столько раз, сколько указано, в данном случае, array.length = 6.

var arr = [];
arr[5] = 'F';

for (var index in arr) {
console.log(index);
console.log(arr[index]);
console.log(arr)
}
// 5
// 'F'
// => (6) [undefined x 5, 6]

arr.forEach(function(element, index, arr) {
console.log(index);
console.log(element);
console.log(arr);
});
// 5
// 'F'
// => Array (6) [undefined x 5, 6]

for (var index = 0; index < arr.length; index++) {
console.log(index);
console.log(arr[index]);
console.log(arr);
};
// 0
// undefined
// => Array (6) [undefined x 5, 6]

// 1
// undefined
// => Array (6) [undefined x 5, 6]

// 2
// undefined
// => Array (6) [undefined x 5, 6]

// 3
// undefined
// => Array (6) [undefined x 5, 6]

// 4
// undefined
// => Array (6) [undefined x 5, 6]

// 5
// 'F'
// => Array (6) [undefined x 5, 6]
2 голосов
/ 04 мая 2018

A for ... в цикле всегда перечисляет ключи. Ключи свойств объектов всегда String, даже индексированные свойства массива:

var myArray = ['a', 'b', 'c', 'd'];
var total = 0
for (elem in myArray) {
  total += elem
}
console.log(total); // 00123
2 голосов
/ 25 декабря 2017

для ... в полезно при работе с объектом в JavaScript, но не для массива, но все же мы не можем сказать, что это неправильный путь, но это не рекомендуется, посмотрите на этот пример ниже, используя для ... в цикле:

let txt = "";
const person = {fname:"Alireza", lname:"Dezfoolian", age:35}; 
for (const x in person) {
    txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

ОК, давайте сделаем это с Array сейчас:

let txt = "";
const person = ["Alireza", "Dezfoolian", 35]; 
for (const x in person) {
   txt += person[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 

Как видите результат тот же ...

Но давайте попробуем что-нибудь, давайте создадим что-то для Array ...

Array.prototype.someoneelse = "someoneelse";

Теперь мы создаем новый массив ();

let txt = "";
const arr = new Array();
arr[0] = 'Alireza';
arr[1] = 'Dezfoolian';
arr[2] = 35;
for(x in arr) {
 txt += arr[x] + " ";
}
console.log(txt); //Alireza Dezfoolian 35 someoneelse

Вы видите кто-то еще !!! ... В этом случае мы фактически перебираем новый объект Array!

Так что это одна из причин, почему нам нужно осторожно использовать для ... в , но это не всегда так ...

0 голосов
/ 24 декабря 2018

, хотя этот вопрос конкретно не рассматривается, я бы добавил, что есть очень веская причина, чтобы никогда не использовать для ... в с NodeList (как можно было бы получить из вызова querySelectorAll, так как он не ' вообще не вижу возвращаемых элементов, вместо этого перебирая только свойства NodeList.

в случае одного результата я получил:

var nodes = document.querySelectorAll(selector);
nodes
▶ NodeList [a._19eb]
for (node in nodes) {console.log(node)};
VM505:1 0
VM505:1 length
VM505:1 item
VM505:1 entries
VM505:1 forEach
VM505:1 keys
VM505:1 values

, который объяснил, почему мой for (node in nodes) node.href = newLink; не удался.

0 голосов
/ 14 января 2018

Поскольку элементы JavaScript сохраняются как стандартные свойства объекта, не рекомендуется перебирать массивы JavaScript, используя for ... in циклы, потому что нормальные элементы и все перечислимые свойства будут в списке.

С https://developer.mozilla.org/en-US/docs/Web/JavaScript/Guide/Indexed_collections

...