Почему используется & ldquo; для & hellip; в & rdquo; с итерацией массива плохая идея?

Если вы хотите удалить их все, просто выполните

this.contentsPanel.Controls.Clear()
1713
задан John Slegers 1 May 2018 в 10:58
поделиться

6 ответов

Причина состоит в том что одна конструкция:

var a = []; // Create a new empty array.
a[5] = 5;   // Perfectly legal JavaScript that resizes the array.

for (var i = 0; i < a.length; i++) {
    // Iterate over numeric indexes from 0 to 5, as everyone expects.
    console.log(a[i]);
}

/* Will display:
   undefined
   undefined
   undefined
   undefined
   undefined
   5
*/

может иногда полностью отличаться от другого:

var a = [];
a[5] = 5;
for (var x in a) {
    // Shows only the explicitly set index of "5", and ignores 0-4
    console.log(x);
}

/* Will display:
   5
*/

Также полагают, что библиотеки JavaScript могли бы сделать вещи как это, которое будет влиять на любой массив, который Вы создаете:

// Somewhere deep in your JavaScript library...
Array.prototype.foo = 1;

// Now you have no idea what the below code will do.
var a = [1, 2, 3, 4, 5];
for (var x in a){
    // Now foo is a part of EVERY array and 
    // will show up here as a value of 'x'.
    console.log(x);
}

/* Will display:
   0
   1
   2
   3
   4
   foo
*/
1501
ответ дан Jorge Fuentes González 1 May 2018 в 20:58
поделиться

Существует три причины, почему Вы не должны использовать for..in для итерации по элементам массива:

  • for..in циклично выполнится по всем собственным и унаследованным свойствам объекта массива, которые не являются DontEnum; это означает, добавляет ли кто-то свойства к определенному объекту массива (существуют допустимые причины этого - я сделал так меня), или изменились Array.prototype (который считают плохой практикой в коде, который, как предполагается, работает хорошо с другими сценариями), эти свойства будут выполнены с помощью итераций также; унаследованные свойства могут быть исключены путем проверки hasOwnProperty(), но это не поможет, Вы с набором свойств в самом объекте массива

  • for..in, как гарантируют, не сохраните элемент, заказывая

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

114
ответ дан Christoph 1 May 2018 в 20:58
поделиться

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

Array.prototype.myOwnFunction = function() { alert(this); }
a = new Array();
a[0] = 'foo';
a[1] = 'bar';
for(x in a){
 document.write(x + ' = ' + a[x]);
}

Это запишет:

0 = foo
1 = bar
myOwnFunction = function() { alert(this); }

И так как Вы никогда не можете быть уверены, что ничто не будет добавлено к опытной цепочке просто, используют, чтобы цикл перечислил массив:

for(i=0,x=a.length;i<x;i++){
 document.write(i + ' = ' + a[i]);
}

Это запишет:

0 = foo
1 = bar
52
ответ дан Praveen Kumar Purushothaman 1 May 2018 в 20:58
поделиться

Поскольку это перечисляет через поля объекта, не индексы. Можно получить значение с индексом "длина", и я сомневаюсь, что Вы хотите это.

16
ответ дан vava 1 May 2018 в 20:58
поделиться

В изоляции нет ничего неправильно с использованием для - в на массивах. Для - в выполняет итерации по названиям свойства объекта, и в случае массива "out-of-the-box", свойства соответствует индексам массива. (Встроенные собственности как length, toString и так далее не включены в повторение. если)

Однако, если Ваш код (или платформа Вы используете) добавят пользовательские свойства к массивам или к прототипу массива, то затем эти свойства будут включены в повторение, которое является, вероятно, не, что Вы хотите.

Некоторые платформы JS, как Прототип изменяет прототип Массива. Другие платформы как JQuery не делают, таким образом, с JQuery можно безопасно использовать для - в.

, Если Вы вызываете сомнение, Вы, вероятно, не должны использовать для - в.

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

for (var ix=0;ix<arr.length;ix++) alert(ix);

Однако это имеет другой вопрос. Проблема - то, что массив JavaScript может иметь "дыры". Если Вы определяете arr как:

var arr = ["hello"];
arr[100] = "goodbye";

Затем массив имеют два объекта, но длину 101. Используя для - в приведет к двум индексам, в то время как для цикла приведет к 101 индексу, где эти 99 имеют значение undefined.

40
ответ дан Eric King 1 May 2018 в 20:58
поделиться

В дополнение к причинам, указанным в других ответах, вы можете не захотеть использовать структуру «for ... in», если вам нужно выполнить математические вычисления с переменной счетчика, потому что цикл повторяется через имена свойств объекта, и поэтому переменная представляет собой строку.

Например,

for (var i=0; i<a.length; i++) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

будет писать

0, number, 1
1, number, 2
...

, тогда как

for (var ii in a) {
    document.write(i + ', ' + typeof i + ', ' + i+1);
}

будет писать

0, string, 01
1, string, 11
...

Конечно, это можно легко преодолеть, включив

ii = parseInt(ii);

] в петле, но первая структура более прямая.

31
ответ дан 22 November 2019 в 20:09
поделиться
Другие вопросы по тегам:

Похожие вопросы: