【问题标题】:Cloning a json object and changing values mutates the original object as well克隆 json 对象并更改值也会改变原始对象
【发布时间】:2017-07-20 15:42:43
【问题描述】:

我想知道为什么会这样?

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

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

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

var modObj = myObj;

之后我从克隆中删除空值:

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

谢谢!

【问题讨论】:

标签: javascript json object


【解决方案1】:

你不是在克隆你只是在用新的变量名引用它。

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

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

【讨论】:

    【解决方案2】:

    你不是在克隆! :/

    替换这个:

    var modObj = myObj;
    

    通过这个:

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

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

    var modObj = myObj.slice();
    

    【讨论】:

      【解决方案3】:

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

      您可以使用Object.assign()

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

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

      【讨论】:

        【解决方案4】:

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

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

        试试这个

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

        【讨论】:

        • 我认为他不会使用 jQuery。他显然正在阅读本地文件,这意味着没有浏览器。
        • 有一个 jQuery npm 包
        • 我应该知道... xD
        【解决方案5】:

        虽然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),因为代码是自我解释的,易于浏览。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-02-21
          • 1970-01-01
          • 2016-01-10
          • 2017-12-16
          • 1970-01-01
          • 2020-03-03
          • 1970-01-01
          • 2015-01-23
          相关资源
          最近更新 更多