extraxt
extraxt

Reputation: 425

Object.assign does not copy correctly

I'm working with VueJS.

I have a Method that receives a Object as argument.

Then I clone this Object with Object.assign().

Component.vue

export default {
  // ...
  methods: {
    // ...
    activateEditMode (item) {
      this.editItemIndex = this.travelItinerary.indexOf(item)
      this.editItem = Object.assign({}, item)
      // ...
    }
  }
}

The original Object at this.roteiroCompleto[0]:

enter image description here

But when I edit the clone Object this.itemEditado:

enter image description here

the original Object this.roteiroCompleto[0] changes too.

enter image description here

I tried to copy each key and value, copy only the Array with .slice(), .map(a=>a), and nothing works. The two objects keep binding.

When I console.log(this.itemEditado), I get this:

enter image description here

The strange thing is, in another Vue Component, I use the same strategy, and it works.

Upvotes: 9

Views: 20293

Answers (5)

Martin
Martin

Reputation: 111

In 2022, to deep clone objects natively on JavaScript you can use structuredClone

The global structuredClone() method creates a deep clone of a given value using the structured clone algorithm.

MDN structuredClone()

Upvotes: 1

Bahaa Samoudi
Bahaa Samoudi

Reputation: 173

Solution from MDN

 Object.assign(this.editItem, JSON.parse(JSON.stringify(item)))

Upvotes: 1

Metin Atalay
Metin Atalay

Reputation: 1517

If the methods you used isn't working well with objects involving data types, try this

import * as _ from 'lodash';

Deep clone object

myObjCopy = _.cloneDeep(myObj);

Upvotes: 5

Andrew Koster
Andrew Koster

Reputation: 1835

You don't have to use a library, unless you really need a deep copy (I did not need one). Just do this:

this.editItem = {...item};

The ... operator will decompose item into its keys and values, and since you're doing that in an object literal (the { }), it uses those as the keys and values of the new object.

Might be helpful to other people who, like me, don't need a deep copy. Object.assign just straight-up doesn't work, and this does.

Upvotes: -2

Garrett Johnson
Garrett Johnson

Reputation: 2534

Object.assign only does a shallow copy of the keys and values, meaning if one of the values in the object is another object or an array, then it is the same reference as was on the original object.

var x = { a: 10, b: { c: 100 } };
var y = Object.assign({}, x);

y.a = 20;
console.log( x.a, y.a ); // prints 10 20

y.b.c = 200;
console.log( x.b.c, y.b.c ) // prints 200 200

To deep copy an object, you can using something like the cloneDeep function in lodash or take an uglier approach using built in functions with JSON.parse( JSON.stringify( obj ) ).

Note that the second option will only work with primitive types that are supported by JSON.

Upvotes: 20

Related Questions