简体   繁体   中英

JS: Does Object.assign() create deep copy or shallow copy

I just came across this concept of

var copy = Object.assign({}, originalObject);

Forget about deep copy, even shallow copy isn't safe, if the object you're copying has a property with enumerable attribute set to false.

MDN :

The Object.assign() method only copies enumerable and own properties from a source object to a target object

take this example

var o = {};

Object.defineProperty(o,'x',{enumerable: false,value : 15});

var ob={}; 
Object.assign(ob,o);

console.log(o.x); // 15
console.log(ob.x); // undefined

By using Object.assign()<\/code><\/strong> , you are actually doing Shallow Copy<\/strong> of your object. Whenever we do an operation like assigning one object to other, we actually perform a shallow copy, ie if OBJ1 is an object, modifying it through another object which is OBJ2 will reflect changes in OBJ1 too.

"

It creates a shallow copy, according to this paragraph from MDN :

For deep cloning, we need to use other alternatives because Object.assign() copies property values. If the source value is a reference to an object, it only copies that reference value.

For the purposes of redux, Object.assign() is sufficient because the state of a redux app only contains immutable values (JSON).

For small Data structures<\/code> I see that JSON.stringify()<\/code> and JSON.parse()<\/code> work nice.

// store as JSON
var copyOfWindowLocation = JSON.stringify(window.location)
console.log("JSON structure - copy:", copyOfWindowLocation)
// convert back to Javascript Object
copyOfWindowLocation = JSON.parse(copyOfWindowLocation)
console.log("Javascript structure - copy:", copyOfWindowLocation)

Other answers are complicated.
Some don't answer the question at all.

Below worked for me

// orignal object with deep keys
var originalObject = {
    k1: "v1",
    k2: "v2",
    deepObj: {
        k3: "v3",
        k4: "v4"
    }
};

// make copies now
var copy1 = JSON.parse(JSON.stringify(originalObject));
var copy2 = JSON.parse(JSON.stringify(originalObject));

Hope that helps.

As mentioned above, Object.assign()<\/code> will do a shallow clone, fail to copy the source object's custom methods, and fail to copy properties with enumerable: false<\/code> .

function shallowClone(src) {
  let dest = (src instanceof Array) ? [] : {};

// duplicate prototypes of the source
  Object.setPrototypeOf(dest, Object.getPrototypeOf(src));

  Object.getOwnPropertyNames(src).forEach(name => {
    const descriptor = Object.getOwnPropertyDescriptor(src, name);
    Object.defineProperty(dest, name, descriptor);
  });
  return dest;
}
var copy = Object.assign({}, originalObject);

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM