Подтвердить что ты не робот

Обрабатывает ли JavaScript array.forEach элементы в порядке возрастания

В JavaScript у меня может быть массив с отверстиями:

a = [];
a[0] = 100;
a[5] = 200;
a[3] = 300;

a.forEach(function(x) {alert(x);});

Я не смог найти информацию о том, будут ли элементы обрабатываться в порядке возрастания, или это ненадежный факт.

Я проверил, что цикл "for.. in" пересекает индексы массива в порядке возрастания, в то время как имена свойств объекта просматриваются в том же порядке, в котором они были добавлены к объекту (по крайней мере, это выглядит так).

(Т.е. похоже, что массивы внутренне являются деревьями некоторого вида, а объекты являются хеш-таблицами.)

Я только что обнаружил, что Rhino JavaScript также пересекает несуществующие элементы: http://ideone.com/7Z3AFh (в отличие от forin).

4b9b3361

Ответ 1

В спецификации ECMA-262, 5th edition и MDN Array.forEach() страница показаны алгоритм для .forEach(), и он будет определенно перебирать элементы массива в порядке возрастания индекса (пропуская индексы, которым никогда не присваивалось значение).

Конечно, некоторые браузеры могут не реализовывать этот алгоритм правильно, но я не знаю никого из них.

Ответ 2

В спецификации указано, что forEach будет посещать элементы массива в числовом порядке. Он не посещает элементы, которые не существуют. Подробнее см. Ссылку. Итак, для вашего массива примеров он будет посещать элемент 0, затем 3, затем 5. Порядок, в котором вы добавляете их в массив, не влияет на порядок, в котором они были посещены.

Я проверил, что цикл "for.. in" обходит индексы массива в порядке возрастания, тогда как имена свойств объекта пересекаются в том же порядке, в котором они были добавлены к объекту (по крайней мере, это выглядит так).

Порядок, в котором for-in посещает свойства объекта, не, определенный спецификацией, даже в ES2015 (ака ES6), несмотря на то, что ES2015 определяет порядок для свойств объекта — этот порядок не применяется к for-in или Object.keys. (Подробнее об этом в этом ответе.) Если вы хотите посетить свойства в порядке, определенном в ES2015, вы можете использовать Object.getOwnPropertyNames (для свойств, которые не определены с именами Symbol) или Reflect.ownKeys (как для Symbol, так и для строковых имен свойств [помните, что имена числовых свойств действительно являются строками]). Оба они уважают порядок собственности.

Ответ 3

Прямо из стандарта ECMAScript

forEach вызывает callbackfn один раз для каждого элемента, присутствующего в массиве, в порядке возрастания. callbackfn вызывается только для элементов массив, который фактически существует; он не называется отсутствующими элементами массив.

Итак, Array.forEach пропустит некоторые элементы в массиве. Ваш пример

a.forEach( function( value ) { console.log( value ) }); // prints 100, 300, 200

Если вы хотите пересечь массив в порядке возрастания, и все ваши элементы являются числами, вы можете отсортировать массив заранее так

a.sort( function( a, b ) { return a - b });
// this now prints 100, 200, 300
a.forEach( function( value ) { console.log( value ) });