Как работает синтаксис распространения в объекте? - PullRequest
0 голосов
/ 27 мая 2018

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

const human = { age: 20 };
const john = { ...human };
john.age = 10;
console.log(human.age); // 20
console.log(john.age); // 10

Как показано выше, человеческий объект может сохранить свое первоначальное значение.Теперь взгляните на код ниже:

const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "camero"]
console.log(john.cars); // ["toyota", "camero"]

Может кто-нибудь объяснить мне, почему произошел описанный выше сценарий?Почему объект машины человека меняется?Мне кажется, что разработчик может ошибаться, не понимая, как избежать противоречивого поведения

1 Ответ

0 голосов
/ 27 мая 2018

Объект human содержит только ссылку на массив, содержащий ["toyota", "honda"].Когда вы дублируете объект с помощью оператора распространения, вы также дублируете ссылку , что означает, что john имеет идентичную ссылку и, следовательно, john.cars - это тот же массив, что и human.cars.

Из-за этого, если вы измените john.cars, вы также измените human.cars, потому что это один и тот же массив.Если вы хотите клонировать массив, вы также можете сделать это с помощью оператора распространения:

const human = { age: 20, cars: ["toyota", "honda"] };
const john = { ...human };
john.cars = [ ... human.cars ];
john.cars[1] = "camero";
console.log(human.cars); // ["toyota", "honda"]
console.log(john.cars); // ["toyota", "camero"]

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

const human = { name: { first: "John", last: "Jackson" } };
const human2 = { ... human };

human2.name.first = "Ellen";

console.log(human.name.first); // Ellen

Это потому, что оператор распространения только копирует ссылку на объект имени, а не сам объект имени.Следовательно, изменение одного изменяет другое, потому что это один и тот же объект.Это называется мелким клонированием .Если вы хотите избежать этой путаницы, вам необходимо выполнить клон глубиной .

Самый простой способ сделать это - преобразовать в JSON, а затем преобразовать обратно:

const human = { name: { first: "John", last: "Jackson" } };
const human2 = JSON.parse(JSON.stringify(human));

human2.name.first = "Ellen";

console.log(human.name.first); // John
console.log(human2.name.first); // Ellen
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...