2017-02-03 3 views
1

Я пытаюсь изменить поле в массиве. Я использовал функцию find, чтобы получить объект, а затем использовал Object.assign, чтобы перезаписать значение из массива.Как работает Object.assign?

Однако в одном случае это работает:

Object.assign(item2, {id:3, name: "Do"});

и в другом случае, это не делает:

item = Object.assign({}, {id:3, name: "Do"});

Что изменилось за эти два случая?

let arr = [{id:1, name:"John"}, {id:2, name: "Doe"}]; 
 
let item = arr.find((x)=> x.id === 2); 
 

 
//the array is not changed! 
 
item = Object.assign({}, {id:3, name: "Do"}); 
 
console.log(arr); 
 

 
let item2 = arr.find((x)=> x.id === 2); 
 
//the array is changed! 
 
Object.assign(item2, {id:3, name: "Do"}); 
 
console.log(arr);

Источник: http://jsbin.com/mametudemo/1/edit?html,js,console

+2

Вы переписываете 'item', когда вы делаете' item = Object ... 'поэтому' item' больше не является частью массива. – dfsq

+0

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

ответ

0

Вы

let item = arr.find((x)=> x.id === 2);

и

let item2 = arr.find((x)=> x.id === 2);

В обоих случаях переменные являются "ссылка" на тот же объект, объект, содержащийся внутри массива arr. Это означает, что если вы меняете какой-либо из них, изменения отражаются на других (даже в массиве), потому что они действительно относятся к одному и тому же объекту.

Теперь вы изменяете две переменные двумя разными способами. В этом случае

Object.assign(item2, {id:3, name: "Do"});

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

Во втором случае:

item = Object.assign({}, {id:3, name: "Do"});

Вы сливаясь новые значения в новом объекте (первый параметр Назначают {}), а затем вы перезаписать переменную item с ним. Теперь item больше не является ссылкой на объект внутри массива. Это новый объект, и, следовательно, объект внутри массива не затрагивается.

1

В первом случае, вы создаете новый объект и присвоить его item. arr[1] не меняется, потому что вы не использовали ссылку на него, как

arr[1] = Object.assign({}, { id: 3, name: "Do" }); 

При втором подходе, вы берете объект и изменить свойство с данным объектом.

let arr = [{ id: 1, name: "John" }, { id: 2, name: "Doe" }]; 
 
let item = arr.find((x) => x.id === 2); 
 

 
item = Object.assign({}, { id: 3, name: "Do" }); 
 
console.log(arr);        // the array is not changed! 
 

 
let item2 = arr.find((x) => x.id === 2); 
 
Object.assign(item2, { id: 3, name: "Do" }); 
 
console.log(arr);        // the array is changed!

0

Существует опечатка/ошибка в коде, заставляя его, чтобы не работать.

При первом попытке изменить объект, который вы используете, item = Object.assign({}, {id:3, name: "Do"});. Обратите внимание на {} как первый параметр для Object.assign ... который должен быть item.

let arr = [{id:1, name:"John"}, {id:2, name: "Doe"}]; 
 

 
let item = arr.find((x)=> x.id === 2); 
 
//the array is not changed! 
 
Object.assign(item, {id:3, name: "Do"}); 
 
console.log(arr); 
 

 
let item2 = arr.find((x)=> x.id === 3); 
 
//the array is changed! 
 
Object.assign(item2, {id:3, name: "Doa"}); 
 
console.log(arr);

+0

Это была не опечатка, а по дизайну. Я хотел понять, почему один подход работает, а другой - нет. – uglycode

+0

Как только я увидел другие решения, я понял, что, возможно, неверно истолковал ваш подход. –

1

Вот что происходит. Вы найдете item:

let item = arr.find((x)=> x.id === 2); 

На данный момент item является ссылкой к соответствующему элементу массива. Когда вы позже сделать задание:

item = Object.assign({}, {id:3, name: "Do"}); 

вы перезаписать значение item (ранее это была ссылка) на новый объект, который не является ссылкой на исходный массив больше. Следовательно, на массив не влияет.

0

Первый аргумент Object.assign - target.

Это используется для добавления свойств, а затем ссылки на один и тот же объект.

Итак, в первом случае свойства добавляются к существующему объекту item2.Но если присвоить это переменной сказать temp и сделать temp.id = 10, это также будет меняться в item2

Чтобы избежать этого, item = Object.assign({}, {id:3, name: "Do"}); используется. Это скопирует все свойства в пустой объект и вернет ссылку. Таким образом, в основном вы скопировали объект, а не только ссылку.