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] имущество).

Другие вопросы по тегам