Reputation: 2031
I was wondering why does this happen?
I have an object stored in var myObj:
var myObj = JSON.parse(fs.readFileSync('json/data.json', 'utf8'));
then I take a clone from the original object by:
var modObj = myObj;
After that I remove empty values from clone:
cleansedObj = removeEmpty(modObj);
Why does this also mutate the original myObj and remove empty values from that too?
here is the function:
function removeEmpty(obj) {
Object.keys(obj).forEach(function(key) {
if (obj[key] && typeof obj[key] === 'object') removeEmpty(obj[key])
else if (obj[key] === "") delete obj[key]
});
return obj;
};
I found a workaround by doing this, but seems like uneccesary operation:
var cleansedObj = JSON.stringify(myObj);
cleansedObj = removeEmpty(JSON.parse(cleansedObj));
Thanks!
Upvotes: 3
Views: 5136
Reputation: 12637
although JSON.parse(JSON.stringify(myObj))
may seem simple and tempting, especially for bigger data structures it is not, because it has to serialize the objects and then parse this string again. I'd reccomend something like this:
function clone(deep, obj=undefined){
var fn = clone[deep? "deep": "shallow"] || function(obj){
return (!obj || typeof obj !== "object")? obj: //primitives
Array.isArray(obj)? obj.map(fn): //real arrays
deep?
//make a deep copy of each value, and assign it to a new object;
Object.keys(obj).reduce((acc, key) => (acc[key] = fn(obj[key]), acc), {}):
//shallow copy of the object
Object.assign({}, obj);
};
return obj === undefined? fn: fn(obj);
}
clone.deep = clone(true);
clone.shallow = clone(false);
and then
//make a deep copy
var modObj = clone.deep(myObj);
//or
var modObj = clone(true, myObj);
//or a shallow one
var modObj = clone.shallow(myObj);
//or
var modObj = clone(false, myObj);
I prefer this style clone.deep(whatever)
because the code is self explaining and easy to scan over.
Upvotes: 1
Reputation: 926
If you use jQuery, then you can do this
var mobObj = jQuery.extend(true, {}, myObj);
else try this
var mobObj = Object.assign({}, myObj);
Upvotes: 1
Reputation: 133403
You are not cloning, you are just passing the reference to myObj
to modObj
.
You can use Object.assign()
var modObj = Object.assign({},myObj);
The
Object.assign()
method is used to copy the values of all enumerable own properties from one or more source objects to a target object. It will return the target object.
Upvotes: 4
Reputation: 1949
You are not cloning ! :/
Replace this:
var modObj = myObj;
By this:
var modObj = JSON.parse(JSON.stringify(myObj));
If myObj is an array do this:
var modObj = myObj.slice();
Upvotes: 3
Reputation: 121998
You are not cloning you are just refering the same with new variable name.
Create a new object out of existing and use it
var modObj = JSON.parse(JSON.stringify(myObj));
Upvotes: 9