Почему Object.assign работает с массивом?

Итак, я читал статью, чтобы клонировать объект и массив. Все они упоминали, что Object.assign() может использоваться для копирования объекта, но никто не упомянул, что Object.assign() также будет работать для поверхностного копирования массива.

Кто-нибудь может объяснить, как это работает?

Code to Explain is in JS Bin : https://jsbin.com/kaqocixize/edit?js,console

3 ответа

JS является прототипно-ориентированным языком. Это означает, что каждая конструкция в JS на самом деле - объект!:)

Объекты отличаются по некоторым метаданным, например, по конкретным свойствам. Они обычно доступны только для чтения, и нет простого способа их переопределить (например, length, name, arguments и многое другое).

В вашем случае массив можно интерпретировать как конкретный объект, где length относится к числу элементов массива, и каждый элемент массива относится к свойству объекта, который использует индекс в качестве ключа:

const array = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  'length': 3,
};

(это упрощение, так как нам все еще не хватает генератора для перебора, который обычно хранится в виде символа).

JS обычно скрывает эти специальные свойства, используя символы - подробнее о них здесь: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Symbol

Однако из-за прототипа JS при использовании Object.assignМассив обрабатывается как объект и, следовательно, выполняется:

Object.assign([],a,['x']); 

вы на самом деле создаете новый массив и переопределяющий элемент 0 с 'x', Вот как эту строку можно интерпретировать в объектном мире:

Object.assign({}, {
  '0': 'a',
  '1': 'b',
  '2': 'c',
}, {
  '0': 'x'
});

И вот как x приземлился как первый индекс нового массива!

Однако есть некоторые различия в реализации Array между ES5 и ES6 - подробнее об этом здесь: http://2ality.com/2014/05/es6-array-methods.html

Как говорится в комментарии Марка Мейера, массивы - это объекты.

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

Итак, в этом коде (пожалуйста, включите такой код в свой вопрос, а не указав на внешний сайт):

var a = ['a','b','c']; 
var b = Object.assign([], a, ['x']);

все, что происходит, это то, что он принимает начальное значение передано, [] а затем добавляет свойства из a на него, свойства которого ключи '0', '1', а также '2'с соответствующими значениями 'a', 'b', а также 'c', а затем добавляет свойства из ['x'] на него, единственный из которых является ключевым '0' со значением 'x', уступая ['x', 'b', 'c'],

Так что это простая обработка объектов.

Обратите внимание, что если вы сделали

Object.assign([], a, [, 'x']);

ты бы получил ['a', 'x', 'c']и если бы вы сделали

Object.assign([], a, [, , , , 'x']);

ты бы получил ["a", "b", "c", undefined, "x"]

Массивы действительно являются объектами в Javascript с некоторыми собственными отличиями и особенностями, поэтому Object.assign способен учитывать и обрабатывать это. Вот еще один вопрос с довольно солидными ответами, который должен помочь вам разобраться в этом.

Являются ли массивы Javascript примитивами? Строки? Объекты?

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