2016-09-10 4 views
1

В спецификации ECMAScript array.length не определяется как количество элементов в массиве.Как узнать количество элементов в массиве Javascript?

http://www.ecma-international.org/ecma-262/6.0/#sec-properties-of-array-instances-length

The length property of an Array instance is a data property whose value is always numerically greater than the name of every configurable own property whose name is an array index.

То есть, двигатель Javascript может привести к array.length положительной бесконечности во всех случаях, и будет совместим со стандартом.

Принимая это во внимание, как следует считать элементы в массиве?

+0

Из того, что я понимаю из вашего вопроса, вы обеспокоены тем, что кто-то перезапишет свойство 'array.length'. Это верно? Если это так, просто используйте любой 'forEach', например @RedMercury, или' for in', чтобы перебрать ваш массив и подсчитать длину. – shriek

+0

По крайней мере, Chrome отклоняет установку 'array.length' до бесконечности:' Uncaught RangeError: недопустимая длина массива'. – Seb

+0

Это очень теоретическая проблема: я знаю, что на практике array.length имеет очень сильное отношение к числу элементов в массиве. –

ответ

1

Это не только спецификация length собственности.

В описании абстрактной операции ArrayCreate(length, proto) указано, что свойство length инициализировано параметром length.

И спецификация Array Exotic Objects объясняет, как это обновление:

Specifically, whenever an own property is added whose name is an array index, the value of the length property is changed, if necessary, to be one more than the numeric value of that array index

Другие манипуляции массива определяются в терминах этих операций, поэтому length свойство должно точно отражать индексы элементов массива.

1

Что? Просто используйте array.length. Я уверен, что не существует реализации стандартов, которые задают длину массива положительной бесконечности.

Если по какой-то причине вы действительно не хотите использовать array.length, просто используйте forEach.

var arrLength = 0; 
arr.forEach(function() { 
    arrLength++ 
}) 
+0

В некотором роде, неверно: 'var x = [9]; x.length = 10; 'и ваша функция повторяется 10 раз, а не 1. Кроме того,' var y = [9, 10, 14]; y.length = 1; console.log (y); 'показывает только' [9] '. – Seb

+0

@Seb, что на самом деле неверно на обеих учетных записях для массива 'x', выше сказанное даст вам' arrLength' '1'. Что касается массива 'y', установите длину массива ниже _truncates_ it. Вы действительно удаляете из него значения '10' и' 14', потому что вы говорите, что в массиве есть один элемент. – vlaz

+0

Неплохо, я не проверял. Но '.shift()' и '.pop()' будут давать разные результаты. – Seb

0

Замена .length имущества запрещена Chrome. Запустить:

var x = []; 
 
x.length = +Infinity; // Uncaught RangeError: Invalid array length

Так, к счастью, нет риска здесь. For Завершение цикла Бесконечность. Вероятно, это закончится несколько раньше из-за некоторого конца памяти.

Но все же можно изменить length просто так. Что произойдет, если мы сделаем это больше?

var x = [9]; 
 
console.log(x); // [9] 
 

 
x.length = 10; 
 
console.log(x); // still [9], although length is 10 this time 
 

 
// example from Red Mercury 
 
x.forEach(function (item, index) { 
 
    console.log('Item', index, item); 
 
}); 
 
    
 
// will print: Item 0 9 
 
    
 
// But... 
 
do { 
 
    console.log(x.shift()); 
 
} while(x.length > 0); // .shift() and .pop() update .length property 
 

 
// will print 9 once, and nine times undefined 
 
// probably the same with .pop(), just in reversed order

И меньше?

var x = [9, 10, 14]; 
 
console.log(x); // [9, 10, 14] 
 

 
x.length = 1; 
 
console.log(x); // [9] 
 

 
// example from Red Mercury 
 
x.forEach(function (item, index) { 
 
    console.log('Item', index, item); 
 
    }); 
 
    
 
// will print: Item 0 9 
 
    
 
// But... 
 
do { 
 
    console.log(x.shift()); 
 
} while(x.length > 0); 
 

 
// will print only 9

Таким образом, хотя большая длина может быть проверена с .forEach() меньше не может. Не рекомендуется изменять значение длины (потому что .forEach() и .shift() начинают «desynchronize»), но в вашем собственном коде это не должно произойти с вами. Я не думаю, что этот язык должен быть полностью пуленепробиваемым, и это невозможно. Реальность проверит его в конце с нарушением скрипта в браузере, и это может сильно ограничить программистов.Если бы у JavaScript был бы правильный массив, а не только массив, подобный объектам, это было бы предотвращено, но это то, что оно есть.

Смежные вопросы