Compare and copy Objects in JavaScript

Tram Ho

Objects in JavaScript

The main difference between object and other primitive data types is that object stores data by reference. So comparing two objects in JavaScript is by address


Reference data type

When assigning an object to a variable, the variable is actually storing the address in the object’s memory.

When we access a property of an object, the interpreter will use the stored address to retrieve the correct value from memory. For example:

In the above example, I initialize the object p1 . Next, I initialize p2 and assign it with p1 . Then I change the x attribute value in p2 . But the result is that p1.x and p2.x both change.

This shows that p2 and p1 are pointing at the same location in memory.

1. Compare 2 objects

1.1. Compare 2 objects by reference

JavaScript provides two comparison operators == and ===, where:

  • The === (“strict equality”) operator returns true if and only if the two variables have the same data type and the same value, false otherwise.
  • The == operator returns true when two variables have the same value and may have different data types (JavaScript will return the same data type for comparison), otherwise it returns false.

For object-by-reference comparison : two objects are said to be equal if and only if they both refer to the same memory address.

Example two objects are equal by reference:

In the above example, two objects x and y are referencing the same address. So they are completely equal.

Conversely, two independent objects will never be equal, even though they look similar.

In addition to the above two operators, you can use the Object.is (value1, value2) function to compare two JavaScript objects by reference.

1.2. Compare 2 objects by value manually

manually compare each value for each property of the object. And I consider two objects equal when they have the same properties and the same value for each property.

For example, build a drawing problem, then each point on the screen is a point with coordinates (x,y) . Then, two points are equal when they have the same coordinates (x,y) , for example:

To manually compare objects, we will access the values ​​of the two properties x and y in each object and then compare them with each other.

In the above example, I wrote the function isPointEqual to compare each drug in the object.

However, if the number of attributes is larger, it is necessary to optimize the function written above. To solve the above problem, I will write a for…in loop to go through all the properties.

The idea of ​​the above algorithm is: iterate over all the properties of an object and compare the corresponding value in the two objects. If the two values ​​are different then the conclusion is that the two objects are not equal.

If two cases return false does not occur, then the two points are equal, so finally return true .

However, this comparison is true only when the values ​​of the property are primitive values. If the value of the property is an object then:

when looping, iterates to metadata because it is an object type, so when comparing, the output is different.

=> Thus, the shallow comparison algorithm is only correct when the values ​​of the properties in the object have primitive data types.

To solve the above problem we have to use a recursive algorithm to traverse all the classes of the object.

after using recursive algorithm to compare the value for each attribute.

2. Copy Object in JavaScript

Next, copying Object in JavaScript is like comparing object, actually copying the address of the property.

2.1. Copy object using for…in . loop

The simplest way to copy an object in JavaScript is to use a for…in loop to iterate over all the properties of the object. Then get the value for each property to assign to the new object.

Example copy object with for…in :

You see, the values ​​of the x and y attributes of p2 are exactly the same as p1. But when changing the value of p2.x = 5, the value of p1.x remains unchanged.

2.2. Shallow copy

In addition to using the for…in loop as above, you can use the same function as Object.assign() with the syntax:

The above method will copy all the properties of the source objects src1, src2,…,srcN to the destination object dest. And the return value is the destination object dest.

Example using Object.assign:

However, it also only copies on one level. If the value of the property in the object is an object, then the object will not be completely independent of the source object.

For example:

In the above example, even though I use the Object.assign() function to copy point1 to point2 , when I change the object at point2 , the metadata changes along with it.

In addition, we can also use the spread (…) syntax which is used to copy the properties of an object into the new object.

However, it can be seen that when there is one or more other objects in the object, this copy is saving as the address of the child objects.

2.3. Deep copy

To solve the problem when we can only copy the child objects below the address, we need to use the JSON.stringify() function to convert the object to JSON format. Then, you use the JSON.parse() function to recreate a new object from the JSON.

It can be seen that when using JSON.stringify() and JSON.parse , the value of metadata at point2 cos changes, but at point1 , the metadata remains the same. That is deep copy.

actually, there is 1 more case, that is a property in object is a function. when we use JSON.stringify() , the function will be converted to “undefined”.

yes, so I came up with another way to handle this case. Just like Object comparison I also use recursion to handle it.

With the deepCopy function, when there are child objects in the object, it will recursively and return a completely independent object. In fact, we can use the _.cloneDeep(value) function of lodash to handle this if this is the case.

Share the news now

Source : Viblo