javascript - разница между массивом и объектом, похожим на массив
Я часто встречал термин "объект в виде массива" в javascript. Что это? Какая разница между ним и обычным массивом? В чем разница между массивоподобным объектом и обычным объектом?
5 ответов
Что это?
Объект, у которого есть свойство длины неотрицательного целого числа и обычно некоторые индексированные свойства. Например
var ao1 = {length: 0}, // like []
ao2 = {0: 'foo', 5: 'bar', length: 6}; // like ["foo", undefined × 4, "bar"]
Вы можете конвертировать Array-подобные объекты в их аналоги Array, используя Array.prototype.slice
var arr = Array.prototype.slice.call(ao1); // []
Какая разница между ним и обычным массивом?
Это не построено Array
или с литералом Array []
и поэтому (обычно) не наследуют от Array.prototype
, Свойство длины обычно также не обновляется автоматически.
ao1 instanceof Array; // false
ao1[0] = 'foo';
ao1.length; // 0, did not update automatically
В чем разница между массивоподобным объектом и обычным объектом?
Нет никакой разницы. Даже обычные массивы являются объектами в JavaScript
ao1 instanceof Object; // true
[] instanceof Object; // true
Известный HTMLCollection
и arguments
массивоподобный объект, который создается автоматически.
Некоторый быстрый массив (например, HTMLCollection
) различия между реальными примерами массивов:
var realArray = ['value1', 'value2'];
var arrayLike = document.forms; //there are 2 forms in the DOM.
arrayLike.length; // returns 2;
realArray.length; // returns 2;
arrayLike[0]; // returns an element.
realArray[0]; // returns an element. ('value')
arrayLike.join(", "); // returns Uncaught TypeError: arrayLike.join is not a function (also relevant to `concat()`, `includes()` etc.)
realArray.join(", "); // returns "value1, value2"
typeof arrayLike; // returns "object"
typeof realArray; // returns "object"
Array.isArray(arrayLike); //returns "false"
Array.isArray(realArray); //returns "true"
arrayLike.length = 1;
arrayLike.length; //return 2;
realArray.length = 1;
realArray.length; //return 1;
Начнем с того, что массив — это специализированный объект. Специализируется на этом:
- Существует специальный литеральный синтаксис
[ … ]
- Есть свойство, которое автоматически обновляется
- Прототип массива включает в себя функции, которые вы обычно ожидаете от массива.
Другой очевидной особенностью является то, что все элементы имеют числовой индекс.
С точки зрения JavaScript любой объект, у которого есть свойство, достаточно близок, чтобы его можно было рассматривать как объект, подобный массиву:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
console.log(arrayLikeObject);
Свойство не обязательно должно быть правильным. Даже в обычном массиве можно принудительно
length
отличаться от количества фактических элементов. Все недостающие элементы возвращаются
undefined
.
Вы можете преобразовать объект, подобный массиву, в настоящий массив, используя . Эта функция будет принимать различные значения, но самое простое выглядит примерно так:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
var array = Array.from(arrayLikeObject);
console.log(array);
С этого момента массив имеет все обычные свойства и методы. В приведенном выше примере свойство
[1]
копируется в новый массив, но элемент
[name]
нет, так как он не принадлежит реальному массиву.
The
Array.from()
function также принимает функцию отображения в качестве второго параметра. Это позволяет вам вносить любые необходимые изменения в пути:
var arrayLikeObject = {
length: 3,
name: 'thing',
'1': 'hello'
};
var array = Array.from(arrayLikeObject,
(element,index) => element?element.toUpperCase():`Item ${index}`
);
console.log(array);
Также есть разница в производительности. В этом видео Матиас Биненс рекомендует использовать массив вместо объекта, подобного массиву, поскольку V8 оптимизирован для обычных массивов.
Я думаю, что в ES6, что-то похожее на массив, если оно итеративное (имеет [Symbol.iterator]
имущество).