Hi, sometimes there is a problem with using consle.log to log objects, let's discuss it.
Problem
So firstly this happen only with logging Javascript Objects
how to generate the issue?
const ourObject = {
property: "property_value"
}
console.log(ourObject)
In this situation the expected console output should be something like this
But what if we have another function that run after this code and make some changes for our object
const ourObject = {
property: "property_value"
}
console.log(ourObject)
function updateObjectFn(obj){
obj.property = "property_value_updated"
}
updateObjectFn(ourObject)
The expected output for the console log here should be the same as the prvious console.log result as we call updateObjectFn after console.log(ourObject)
But the log will be something interesting it will show the property as updated even we have updated it after log
So what is happening, most of the browsers show on the console the current state of the object on the memory not the object at the time of logging it.
And that happen special with object as it Mutable
Same issue happen with arrays as it also objects on Javascript
Solution
In fact there is many solutions for this situation
1. Pass update function a copy of the object to avoid data mutation
for simple objects we can do shallow copy using destructing
const ourObject = {
property: "property_value"
}
console.log(ourObject)
function updateObjectFn(obj){
obj.property = "property_value_updated"
}
updateObjectFn({...ourObject})
if the object is nested we can use some utility tools like Lodash function deepClone
const ourObject = {
property: "property_value",
nestedProperty: {
key: "key_value"
}
}
console.log(ourObject)
function updateObjectFn(obj){
obj.property = "property_value_updated"
obj.nestedProperty.key = "key_value_updated"
}
updateObjectFn(_.cloneDeep(ourObject))
NOTE: take care about coping too many objects as increase the usage of the memory
By the end Will discuss another approach to avoid mutations without having a deep memory effect.
2. By making Stringify copy of the object
Make a stingify copy of the object before logging it.
const ourObject = {
date: new Date() ,
property: "property_value"
}
console.log(JSON.parse(JSON.stringify(ourObject)))
function updateObjectFn(obj){
obj.date = new Date("1/1/2022")
obj.property = "property_value_updated"
}
updateObjectFn(ourObject)
Although, it loses some information about the properties on the object of some data types as Example Date here.
3. Use immutable data types.
There is some Javescript package that provide immutable data types
on an elegant way without having deep effect on the memory usage.
Examples: immutable-js Immer
Same Problem with React devTools.
you Might face this same problem with React devTools
As this screen as the devTools show that the object as
Updated but it is not updated on the screen.
This issue happen if the state of the application updated directly
without using setState
method
As this example here
I think that it, Thanks for reading I hope you enjoyed going throught it🙂.
Any feedback would be greatly appreciated.
Top comments (0)