assign() The Object. assign() method copies all enumerable own properties from one or more source objects to a target object. It returns the modified target object.
In this article, we learned what it means to shallow copy and to deep copy an object. We also learned that we can use the copy() method of the copy module to create a shallow copy, and the deepcopy() method to create a deep copy of the compound objects.
The spread operator makes deep copies of data if the data is not nested. When you have nested data in an array or object the spread operator will create a deep copy of the top most data and a shallow copy of the nested data.
Object. assign() provides shallow copying (Only properties and methods) and it will override the method and property declared. while Object. create() provides Deep copying provides prototype chain.
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()
, you are actually doing Shallow Copy of your object. Whenever we do an operation like assigning one object to other, we actually perform a shallow copy, i.e. 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
I see that JSON.stringify()
and JSON.parse()
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()
will do a shallow clone, fail to copy the source object's custom methods, and fail to copy properties with enumerable: false
.
Preserving methods and non-enumerable properties takes more code, but not much more.
This will do a shallow clone of an array or object, copying the source's methods and all properties:
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;
}
Example:
class Custom extends Object {
myCustom() {}
}
const source = new Custom();
source.foo = "this is foo";
Object.defineProperty(source, "nonEnum", {
value: "do not enumerate",
enumerable: false
});
Object.defineProperty(source, "nonWrite", {
value: "do not write",
writable: false
});
Object.defineProperty(source, "nonConfig", {
value: "do not config",
configurable: false
});
let clone = shallowClone(source);
console.log("source.nonEnum:",source.nonEnum);
// source.nonEnum: "do not enumerate"
console.log("clone.nonEnum:", clone.nonEnum);
// clone.nonEnum: – "do not enumerate"
console.log("typeof source.myCustom:", typeof source.myCustom);
// typeof source.myCustom: – "function"
console.log("typeof clone.myCustom:", typeof clone.myCustom);
// typeof clone.myCustom: – "function"
jsfiddle
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With