克隆json对象并更改值也会改变原始对象

时间:2017-03-01 10:44:48

标签: javascript json object

我想知道为什么会这样?

我有一个存储在var myObj中的json对象:

var myObj = JSON.parse(fs.readFileSync('json/data.json', 'utf8'));

然后我通过以下方式从原始对象中获取克隆:

var modObj = myObj;

之后我从clone中删除空值:

cleansedObj = removeEmpty(modObj);

为什么这也会改变原始myObj并从中删除空值?

这是功能:

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

我通过这样做找到了解决方法,但似乎是不成功的操作:

var cleansedObj = JSON.stringify(myObj);
cleansedObj = removeEmpty(JSON.parse(cleansedObj));

谢谢!

5 个答案:

答案 0 :(得分:7)

你没有克隆你只是用新的变量名来引用它。

创建一个现有的新对象并使用它

string

答案 1 :(得分:4)

您没有克隆,您只是将对myObj的引用传递给modObj

您可以使用Object.assign()

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

Object.assign()方法用于将所有可枚举的自有属性的值从一个或多个源对象复制到目标对象。它将返回目标对象。

答案 2 :(得分:3)

你不是克隆人! :/

替换它:

var modObj = myObj;

由此:

var modObj = JSON.parse(JSON.stringify(myObj));

如果myObj是一个数组,请执行以下操作:

var modObj = myObj.slice();

答案 3 :(得分:1)

如果您使用jQuery,那么您可以这样做

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

否则试试这个

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

答案 4 :(得分:1)

虽然JSON.parse(JSON.stringify(myObj))可能看起来简单而有诱惑力,特别是对于更大的数据结构而言,它不是,因为它必须序列化对象然后再次解析这个字符串。我推荐这样的事情:

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

然后

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

我更喜欢这种风格clone.deep(whatever),因为代码是自我解释并且易于扫描。

相关问题