Почему 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 примитивами? Строки? Объекты?