Почему, когда я меняю копию объекта в TS, оригинальная тоже меняется? - PullRequest
0 голосов
/ 05 июня 2019

Я импортирую избыточное хранилище и использую оператор распространения для создания копии свойства магазина. Затем, когда я изменяю эту копию, оригинальное свойство также изменяется.

Когда я использую copy = JSON.parse(JSON.stringify(original)) все работает нормально.

export const move = (moveData: IMove): BoardActionTypes => {
  const { board } = store.getState();
  console.log(board.pieces.byId["19"]); // {row: 3, col: 7}

  const newById: IPiecesById = { ...board.pieces.byId };

  newById["19"].col = 4;
  newById["19"].row = 4;

  console.log(board.pieces.byId["19"]); // {row: 4, col: 4}
  console.log(newById["19"]); // {row: 4, col: 4}

  //...
};

Ответы [ 3 ]

2 голосов
/ 05 июня 2019

Ваш вопрос о мелкой VS глубокой копии объекта.

При использовании оператора распространения вы создаете мелкую копию объекта (точно так же, как при использовании old-school Object.assign ).

Когда вы используете разбор JSON - вы получаете глубокую копию (или "глубокий клон") объекта.

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

Возможно, вы захотите прочитать мой вопрос по этому вопросу , а также эту статью .

0 голосов
/ 05 июня 2019

Что с вами происходит - два объекта с одинаковой ссылкой.

Если вы не хотите использовать внешнюю библиотеку или вспомогательную функцию (если вы не собираетесь использовать ее широко), вы можете использовать что-то вроде этого:

const newById = board.pieces.byId.map((item) => ({ ...item }));

(я предположил, что byId является массивом, а карта создает новый массив)

0 голосов
/ 05 июня 2019

У меня есть 2 варианта для этого.

1.Использование underscore.js

var foo = { row: 0, col:0 };
var bar = _.clone(foo);
bar.row = 99;

console.log(foo);
console.log(bar);
<script src="https://cdnjs.cloudflare.com/ajax/libs/underscore.js/1.9.1/underscore.js"></script>

2.ваниль JS

function clone(obj) {
  if (obj === null || typeof(obj) !== 'object')
  return obj;

  var copy = obj.constructor();

  for (var attr in obj) {
    if (obj.hasOwnProperty(attr)) {
      copy[attr] = obj[attr];
    }
  }

  return copy;
}

var foo = { row: 0, col: 0 };
var bar = clone(foo);
bar.row = 99;

console.log(foo);
console.log(bar);
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...