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

Недопустимая длина массива Javascript для массива объектов

Может ли кто-нибудь объяснить это (странное) поведение? Почему длина в первом примере 3, а не 2, а самое главное, почему длина во втором примере 0? До тех пор, пока ключи являются численными, длина работает. Когда их нет, длина равна 0. Как я могу получить правильную длину из второго примера? Спасибо.

a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"};
alert(a.length); // returns 3

b = [];
b["key1"] = {"string1":"string","string2":"string"};
b["key2"] = {"string1":"string","string2":"string"};
alert(b.length); // returns 0
4b9b3361

Ответ 1

Следует отметить, что существует разница между регулярными массивами и ассоциативными массивами. В регулярных массивах (реальных массивах) индекс должен быть целым числом. С другой стороны, ассоциативные массивы могут использовать строки как индекс. Вы можете придумать ассоциативные массивы как карту, если хотите. Теперь также обратите внимание, что истинные массивы всегда начинаются с нуля. Таким образом, в вашем примере вы создали массив следующим образом:

a = [];
a["1"] = {"string1":"string","string2":"string"};
a["2"] = {"string1":"string","string2":"string"}

Javascript смог преобразовать индексы строк в числа, поэтому ваш код выше:

a = [];
a[1] = {"blah"};
a[2] = {"blah"};

Но помните, что я сказал ранее: True массивы начинаются с нуля. Поэтому интерпретатор javascript автоматически назначил [0] на undefined. Попробуйте либо в firebug, либо в консоли Chrome/Safari, и вы увидите что-то подобное, когда вы попытаетесь напечатать "a". Вы должны получить что-то вроде "[undefined, Object, Object]. Следовательно, размер 3 не 2, как вы ожидали.

В вашем втором примере я уверен, что вы пытаетесь имитировать использование связанного массива, который по существу добавляет свойства к объекту. Помните, что связанные массивы позволяют вам использовать строки в качестве ключа. Таким образом, в других терминах вы добавляете свойство к объекту. Итак, в вашем примере:

b["key1"] = {"string1":"string","string2":"string"};

это действительно означает:

b.key1 = {"string1":"string","string2":"string"};

Инициализация b = [] просто создает массив, но ваше назначение не заполняет массив. Он просто дает дополнительные свойства "b". Надеюсь, это поможет..: -)

Ответ 2

Длина

возвращает 1 + наибольший целочисленный ключ в объекте.

В a наибольший ключ равен 2, поэтому 1 + 2 равно 3.

В b нет целых ключей (ключи есть key1 и key2, которые не могут быть преобразованы в int), поэтому Javascript предполагает, что наибольший ключ -1, а 1 + -1 дает 0.

Эта программа поможет вам увидеть, что:

a = [];
a["1"] = {};
a["4"] = {};
alert(a.length); // Prints 5

Ответ 3

Из стандарта ECMAScript ECMA-262, 5-е изд.

15.4.5.2 длина

Свойство length этого объекта Array - это свойство данных, значение которого всегда численно больше, чем имя каждого удаляемого свойства, имя которого является индексом массива.

Обратите внимание, что свойство length массива учитывает только массивные индексы, которые являются целыми числами; установка других свойств не влияет на длину.

Для массива a["3"] эквивалентно a[3] (это поведение указано в п. 15.4.5.1); 3 - это индекс массива, а не свойство. Таким образом, установка a["3"] влияет на длину массива. b["key1"] эквивалентно b.key1. Свойства настройки не влияют на длину коллекции.