Разница между именованными и индексированными массивами - JavaScript - PullRequest
1 голос
/ 11 июня 2019

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

let arr = []
arr.push('a')
arr.push('b')
arr.push('c')
arr.foo1 = 'bar1'
arr.foo2 = 'bar2'

arr.forEach и для итераций только над индексированными значениями, тогда какдля итераций индексов / ключевых значений.

Я думаю, что мне интересно, зачем кому-то это использовать?Одна вещь, которую было бы здорово иметь как в объектах, так и в массиве, - это гарантированный порядок пар ключ-значение

(не только [{key: 'value'}, {key2: 'value2'], но что-тогде вы могли бы использовать for объекта, где порядок будет основан на порядке, в котором были установлены ключи объекта. Я знаю, что это невозможно, но просто предлагаю что-то, что было бы неплохо получить между объектами и массивами)

но похоже, что порядок значений ключей не может быть повторен, поэтому порядок не гарантирован (если я не прав). Это похоже на сочетание объекта и массива., но зачем смешивать, когда вы можете просто создать объект или массив обычным способом?

Ответы [ 2 ]

4 голосов
/ 11 июня 2019

Массивы - это объекты JavaScript, как и любые другие, которые вы создаете.(Почти) все в JavaScript наследует свой прототип от Object.

Теперь спецификация массива такова, что индексы - это просто свойства с конкретными именами.a[1] и a['1'] указывают на одно и то же свойство.Единственное, что вам нужно - это иметь числовое свойство length словах спецификации языка ECMAScript «Массивы - это экзотические объекты, которые предоставляют особую обработку определенному классу имен свойств».

Теперь forEach определяется как функция, которая будетОбходите только те «специальные» свойства, которые есть у экземпляра Array.Он начинается с 0 и заканчивается length - 1 и пропускает неопределенные значения.Это не смотрит на другие реквизиты.Таким образом, вы получаете только поля в массиве.

for of является итератором - если у вас есть объект iterable, вы в основном получаете его функцию итератора, а затем перебираете значения, которые ондает тебе.Итеративный массив дает только те индексированные имена свойств.Вы можете прочитать чуть больше в MDN .

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

Но for in не волнует, является ли этот объект особенным или нет. Он будет просто зацикливаться на ВСЕХ свойствах любого объекта, который вы ему дадите, включая массив. Вот почему, когда вы for in зацикливаете объект, вы зацикливаете свойства объекта, и индексы массива включаются в него.,

Примечание: использование for ... in ... не рекомендуется. Например, в разреженном массиве (где вы устанавливаете, например, [0] = 1, a [10] = 1 иоставьте все остальные индексы неопределенными), for in просто выйдет из этих двух свойств.

Итак, если кто-то даст вам объект со свойствами, называемыми 0 и 10, вы бы назвали его массивом?Нету.Еще одна плохая вещь - это то, что он также пройдет по прототипу объекта и выведет список свойств всех объектов, от которых этот массив мог бы унаследоваться - и вы, вероятно, этого не хотите.

4 голосов
/ 11 июня 2019

Краткий ответ: в JS не существует такого понятия, как «именованный массив».

Модель типов данных JS основана на объектах, которые являются контейнерами пары ключ / значение, а массивы - это особый тип объектов.с дополнительной (родной) логикой для работы с цифровыми клавишами.

Таким образом, все, что вы можете сделать с объектом, вы можете сделать с массивом, но не должны: если вам нужны именованные ключи, используйте объект.Если вам нужны числовые ключи с производными свойствами, такими как length, и служебный API, такой как push / pop / shift / unshift, forEach, map и т. Д., Используйте массив.

Также обратите внимание, что свойство length не говорит ничего о фактическом размере массива в памяти: массивы вообще не похожи на массивы C / Java / etc, а ведут себя скорее как векторы / массивы: они 'просто JS-объекты с числовыми привязками клавиш / пар, поэтому, если вы установите массив [0], а затем установите массив [99], length будет требовать «100», и это число ничего не будет значить: ваш массивв памяти - это просто объект с парой ключ / значение, введенной в строку 0, и парой ключ / значение, введенной в строку 100.

Этот quora answer довольно хороший материал для дальнейшего прочтения, объясняющий все это на основе фактических определений спецификации ECMAScript.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...