Cloning and merging, Object.assign
Copying an object variable creates one more reference to the same object. What if we need to duplicate an object?
We can use the method Object.assign
for that:1
Object.assign(dest[,src1,src2,...])
It copies the properties of all object src1, src2, ...
into dest
. In other words, properties of all arguments starting from the 2nd are copied into the 1st, then it returns dest
1
2
3
4
5
6
7let user = { name: "John"};
let permission1 = { canView: true};
let permission2 = { canEdit: true};
Object.assign(user, permission1, permisson2);
// now user = {name:"John", canView: true, canEdit: true}
If the receiving object (user
) already has the same named property, it will overwritten:1
2
3
4
5
6let user = { name: "John" };
// overwrite name, add isAdmin
Object.assign(user, { name: "Pete", isAdmin: true });
// now user = { name: "Pete", isAdmin: true }
Until now we assumed that all properties of user
are primitive, But properties can be references to other object. What do do with them? Like this:1
2
3
4
5
6
7
8let user = {
name: "John",
sizes: {
height: 182,
width: 50
}};
alert( user.sizes.height ); // 182
Now it’s not enough to copy clone.sizes = user.sizes
, because the user.sizes
is an object, it will be copied by reference. So clone
and user
will share the same sizes. Like this:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15let user = {
name: "John",
sizes: {
height: 182,
width: 50
}
};
let clone = Object.assign({}, user);
alert( user.sizes === clone.sizes ); // true, same object
// user and clone share sizes
user.sizes.width++; // change a property from one place
alert(clone.sizes.width); // 51, see the result from the other one
To fix that, we use “deep cloning” that examine each value of user[key]
, if it’s an object, replicate its structure as well.
There’s a standard algorithm for deep cloning that handles the case above and more complex cases, called the Structured cloning algorithm. We can use an implementation of a JavaScript library lodash, the method is called _.cloneDeep(obj)