Меня смущает деструктивное присвоение в JavaScript мелкой и глубокой копии. Например,

const obj = {key:{}, value:{}}
let {key} = obj
key = {msg: 'hello'}

Является ли значение key в примере выше неглубокой или глубокой копией key в obj? Какое значение должно быть у key?

-2
Kangning Li 21 Янв 2021 в 12:41

2 ответа

Лучший ответ
let {key} = obj

… То же самое, что сказать:

let key = obj.key

Это мелкая копия.


key = {msg: 'hello'}

… Перезаписывает ссылку на объект, который также существует в obj.key, ссылкой на новый объект.

Это делает предыдущую строку бессмысленной, поскольку ничего не было сделано со значением до того, как оно было перезаписано.

2
Quentin 21 Янв 2021 в 09:44

Мелко, но есть нюанс.

Этот:

let {key} = obj;

Имеет точно такой же результат:

let key = obj.key;

Например, все, что он делает, это копирует значение obj.key в key, заставляя оба из них указывать на один и тот же объект - неглубокую копию, если слово «копия» действительно применимо. (Обычно я думаю, что «неглубокая копия» - это копирование нескольких свойств, а не только одного, как это делает Object.assign.)

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

const obj = {
    a: {
        b: {
            c: {
               d: "hi",
            },
        },
    },
};
const {a: {b: {c}}} = obj;
console.log(c.d); // "hi"

Но, в конце концов, это похоже на присвоение, поэтому он просто получает ссылку на объект (если значение является ссылкой на объект), а не копию объекта:

const obj = {
    a: {
        b: {
            c: {
               d: "hi",
            },
        },
    },
};
const {a: {b: {c}}} = obj;
console.log(c.d);         // "hi"
console.log(obj.a.b.c.d); // "hi"
c.d = c.d.toLocaleUpperCase();
console.log(c.d);         // "HI"
console.log(obj.a.b.c.d); // "HI"

Но , даже если бы это была полная копия, ваш код все равно ничего не изменил бы в obj, потому что вы меняете значение того, что находится в key (объект ссылка), а не состояние объекта, на который ссылается ссылка. После let {key} = obj key полностью отключается от obj.key, за исключением того, что они оба ссылаются на один и тот же объект. Если вы измените значение в key, переменной , это не повлияет на объект, на который она ссылается. Если вы собираетесь сделать key = ..., нет никакого смысла в let {key} = obj, просто используйте let key.

1
T.J. Crowder 21 Янв 2021 в 10:04
65824718