【问题标题】:Javascript - How to clone an object?Javascript - 如何克隆一个对象?
【发布时间】:2011-12-19 10:21:40
【问题描述】:

我很困惑。我从myObjOne 创建了一个副本,然后我从myObjOne 中删除了一个条目,JS 也删除了我的副本中的条目(myObjTwo)?但为什么呢?

  myObjOne = {};
  myObjOne['name'] = 'xxx';
  myObjOne['id'] = 'yyy';
  myObjOne['plz'] = 'zzz';  

  // clone
  myObjTwo = myObjOne;

  // remove something
  delete myObjOne['name'];

  console.dir(myObjTwo);

示例 http://jsbin.com/itixes/edit#javascript,html

【问题讨论】:

标签: javascript copy clone


【解决方案1】:

在 ES6 中,使用扩展运算符。

myObjTwo = {...myObjOne}

es6 中的扩展运算符只是一个省略号。 即使原件被销毁,它也会创建原件的副本

【讨论】:

    【解决方案2】:

    您可以使用Object.assign(),但请注意浏览器支持。

    更多信息在这里:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Object/assign

    例子:

    myObjTwo = Object.assign({}, myObjOne);
    

    【讨论】:

      【解决方案3】:

      简单。

      var clone=function(o){
            var n= {}.toString.apply(o)=="[object Array]" ? []:{};
            for(i in o)
               n[i]= typeof o[i]=='object' ? clone(o[i]):o[i];
            return n;
       };
      

      用法:

      var x={a:{d:34},b:33};
      var y=clone(x);  // clones 'x'
      

      【讨论】:

        【解决方案4】:

        你可以像这样使用 jQuery:

        var myObjTwo = jQuery.extend(true, {}, myObjOne);
        

        第一个参数表示我们要制作myObjOne 的深层副本。

        【讨论】:

          【解决方案5】:

          更新:删除 Object.create 作为 cmets 中指示的克隆方法。

            myObjTwo = myObjOne;
          

          不克隆。它只是复制参考。

          如果要克隆,可以使用JSON.parseJSON.stringify

          var x = {a:{b:{c:{'d':'e'}}}};
          var y = JSON.parse(JSON.stringify(x));  //y is a clone of x
          console.log(y.a.b.c.d); //prints e
          console.log(y === x); //prints false
          

          警告:正如 Raynos 在 cmets 中提到的,这个基于 JSON 的克隆不会在输出对象中保留输入对象的方法。如果您的对象不包含任何方法,此解决方案就足够了。方法是作为函数的对象的属性。如果var obj = {add : function(a,b){return a+b;}}addobj 的方法。

          如果您需要一个支持复制方法的解决方案,请查看这些 SO 答案(如 musefan、Matt 和 Ranhiru Cooray 所指出的)

          我建议How do I correctly clone a JavaScript object?

          【讨论】:

          • a={name:1};b=Object.create(a);delete a.name;现在 b 也没有 'name' 属性
          • Object.create 不进行克隆,而是将x 添加到y 的原型链中。
          • @pimvdb , spicavigo 感谢您的指出。删除了Object.create
          • 使用 JSON 进行克隆非常昂贵并且会破坏方法。
          • @Raynos 如果您希望包含更快的方法,请随时更新我的​​答案。我认为对于简单的对象,它足够快速和简洁。我还在发布前检查了 jsperf jsperf.com/clone/2,它看起来具有可比性。无论如何,请随时更新。
          【解决方案6】:

          关于如何复制对象及其属性以及其属性引用的所有对象的大量建议。这是一个克隆对象而不复制它的版本,因此克隆继承了以后添加的所有属性,除了那些被克隆自己的属性遮蔽的属性:

          var cloneOf = (function() {
            function F(){}
            return function(o) {
              F.prototype = o;
              return new F();
            }
          }());
          

          有些人可能会认出这种模式。一个例子:

          var base = {foo:'foo', bar:'bar'};
          var baseClone = cloneOf(base);
          alert(baseClone.foo);  // foo
          

          【讨论】:

          • 为什么你使用原型链而不是复制属性?
          • 因为它是“克隆”对象的一种方式 - OP 没有说明克隆的预期内容,所以一切都会发生。
          • 这很好用。它适用于具有多个嵌套对象/子对象的对象以及函数。克隆对象后,可以删除“原始”,克隆将保持原样。
          【解决方案7】:

          您的myObjTwo = myObjOne 行没有克隆myObjOne,它只是创建了对同一对象的重复引用!

          实际的答案是使用克隆函数,可能来自诸如underscore.js 之类的库。但实际上,您似乎需要阅读和学习 Javascript 中的对象和指针的概念。

          【讨论】:

            【解决方案8】:

            这不是你克隆的方式,它只是将相同的原始对象存储在一个额外的变量中。也许this answer 会帮助你

            【讨论】:

              猜你喜欢
              • 2011-04-15
              • 2016-04-14
              • 2017-05-22
              • 2013-01-03
              • 2014-08-09
              • 2010-10-18
              相关资源
              最近更新 更多