Почему Object.assign работает с массивом? - PullRequest
0 голосов
/ 16 ноября 2018

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

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

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

Ответы [ 3 ]

0 голосов
/ 16 ноября 2018

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

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

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

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

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

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

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

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

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

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

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

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

0 голосов
/ 16 ноября 2018

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

В частности, массив - это объект, ключи которого представляют собой строки, представляющие маленькие целые числа.Существует некоторая магия для обработки того, как 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"]

0 голосов
/ 16 ноября 2018

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

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

...