最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

javascript - Cloning an object and changing values mutates the original object as well - Stack Overflow

programmeradmin0浏览0评论

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!

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!

Share Improve this question edited Jun 25, 2022 at 19:50 jabaa 6,8073 gold badges13 silver badges38 bronze badges asked Mar 1, 2017 at 10:44 Jack M.Jack M. 2,0315 gold badges26 silver badges36 bronze badges 3
  • 4 var modObj = myObj; is not cloning, you are just passing the reference to myObj to modObj – Satpal Commented Mar 1, 2017 at 10:46
  • Probably related (fs.readFileSync feels like Node): Cloning an Object in Node.js – Álvaro González Commented Mar 1, 2017 at 10:49
  • Possible duplicate of How do I correctly clone a JavaScript object? – Álvaro González Commented Mar 1, 2017 at 11:44
Add a comment  | 

5 Answers 5

Reset to default 9

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));

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.

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();

If you use jQuery, then you can do this

var mobObj = jQuery.extend(true, {}, myObj);

else try this

var mobObj = Object.assign({}, myObj);

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.

发布评论

评论列表(0)

  1. 暂无评论