Copying objects
Unlike primitive data types, object data is copied by reference. What does it mean? Consider the following example:
const tom = {name: "Tom"}; const bob = tom; // check the name property of both constants console.log(tom.name); // Tom console.log(bob.name); // Tom // change the name property of the bob constant bob.name="Bob"; // re-check the name property of both constants console.log("After change") console.log(tom.name); // Bob console.log(bob.name); // Bob
First, an ordinary object tom with one property is a defined name. Then we assign the value of this object to a constant bob
const bob = tom;
In this case, the constant bob gets a reference or, relatively speaking, the address of a constant tom, so after this assignment, both constants essentially point to the same object in memory. Accordingly, changes made through one constant:
bob.name="Bob";
Another constant is also affected – tom:
console.log(tom.name); // Bob\
Moreover, let’s add a new property to the object through one of the constants:
const tom = {name: "Tom"}; const bob = tom; // add new property to bob constant - age bob.age = 37; // and we see that a new property has also been added for tom console.log(tom.age); // 37
After adding a property to a constant bob, you can see that the constant tom also has this property, because again, both constants represent the same object.
What if we want to copy from a property of an object, but at the same time both constants or variables would point to completely different objects, changes in one of which would not affect the other in any way? In this case, we can use the built-in Object.assign() method .
Object.assign method
The Object.assign() method takes two parameters:
Object.assign(target, ...sources)
The first parameter target represents the object into which to copy the properties. The second parameter is …sources a set of objects from which to copy properties (that is, we can copy properties from several objects at once)
Returns the method of the target object, into which the properties from the objects are copied sources.
For example:
const tom = { name: "Tom", age: 37}; const bob = Object.assign({}, tom); bob.name = "Bob"; bob.age = 41; console.log(`Объект tom. Name: ${tom.name} Age: ${tom.age}`); console.log(`Объект bob. Name: ${bob.name} Age: ${bob.age}`);
In this case, the call Object.assign({}, tom)means that we are copying the data from the object tom to an empty object {}. The result of this copying is a bob. Moreover, this is a completely different object than tom. And any changes to the constant bob here will not affect the constant in any way tom.
Console output of the program:
tom object. Name: Tom Age: 37 bob. Name: Bob Age: 41 Copy from multiple objects
Similarly, you can copy data from multiple objects:
const tom = { name: "Tom"}; const sam = { age: 37}; const person = { height: 170}; Object.assign(person, tom, sam); // копируем из tom и sam в person console.log(person); // {height: 170, name: "Tom", age: 37}
This copies all the properties from the tom and sam objects to the person object. As a result, after copying, the person object will have three properties.
Copy properties of the same name
If the objects being copied from containing the same properties, then the properties from the last objects replace the properties of the previous ones:
const tom = { name: "Tom", age: 37}; const sam = { age: 45}; const person = { height: 170}; Object.assign(person, tom, sam); console.log(person); // {height: 170, name: "Tom", age: 45}
Here, both objects, tom, and sam, contain a property age, but in the person object, the age property is 45, the value from the sam object, because the sam object is copied last.
Copying object properties
While this Object.assign() works great for simple objects, what happens if the property of the copied object also represents the object:
const tom = { name: "Tom", company: {title: "Microsoft"}}; const bob = Object.assign({}, tom); bob.name = "Bob"; bob.company.title = "Google"; console.log(tom.name); // Tom console.log(tom.company.title); // Google
Here, a company objects property represents an object with a single property. And when copying the bob object, it will not receive a copy of the value tom.company, but a reference to this object. Therefore, the changes bob.company will affect and tom.company.
Copying an object using the spread operator
The spread operator … allows you to spread an object into different pairs property-value that can be passed to another object.
const tom = { name: "Tom", age: 37, company: "Google"}; const bob = {...tom} bob.name = "Bob"; console.log(tom); // {name: "Tom", age: 37, company: "Google"} console.log(bob); // {name: "Bob", age: 37, company: "Google"}
In this case, bob, copies of the properties of the tom object are passed to the object.
If some properties of the new object should have other values (as in the example above, the name property), then they can be specified at the end:
const tom = { name: "Tom", age: 37, company: "Google"}; const bob = {...tom, name: "Bob"}; console.log(bob); // {name: "Bob", age: 37, company: "Google"}
As you can see from the previous example, both constants after copying represent references to different objects, and changing one of them will not affect the other object in any way.
However, if the objects contain nested objects, then these nested objects, when copied, will again essentially represent references to the same object:
const tom = { name: "Tom", age: 37, Company: {title: "Microsoft"}}; const bob = {...tom} bob.name="Bob"; bob.company.title = "Google"; console.log(`${tom.name} - ${tom.company.title}`); // Tom - Google console.log(`${bob.name} - ${bob.company.title}`); // Bob - Google
Object Comparison
Let’s compare two objects using standard comparison and equivalence operations:
const tom = {name: "Tom"}; const bob = {name: "Bob"}; console log(tom == bob); // false console log(tom === bob); // false
Both operators in this case will return the value false, that is, the objects are not equal. Moreover, even if the values of the properties of the objects are the same, then in both cases we will still get false
const tom = {name: "Tom"}; const bob = {name: "Tom"}; console log(tom == bob); // false console log(tom === bob); // false
However, what happens if both constants (variables) store a reference to the same object:
const tom = {name: "Tom"}; const bob = tom; console log(tom == bob); // true console log(tom === bob); // true
In this case, in both cases, we will get true, since the values of both constants are equal since in fact, this is the same value.