JavaScript中的对象克隆

77

以下代码首先记录 0,然后记录 1。我该如何存储对象的副本,而不是它的引用

debug.log(vi.details.segment);
vi.nextSegment = vi.details;
vi.nextSegment.segment++;
debug.log(vi.details.segment);
7个回答

154

使用jQuery克隆一个对象:

var vi.nextSegment = jQuery.extend({}, vi.details);

注意:上面是浅拷贝:任何嵌套的对象或数组都将被引用复制-这意味着您对vi.nextSegment.obj [prop] 所做的任何更改都将反映在vi.details.obj [prop] 中。 如果您想要一个与原始对象完全不同的新对象,则需要进行深层复制(将true作为第一个参数传递):

var vi.nextSegment = jQuery.extend(true, {}, vi.details);

如果想要深入了解extend,可以看看这里


11
这不是一份深拷贝。var a = {b: [1, 2]}; $.extend({}, a).b[0] = 'test';,然后a.b[0]的值变成了'test'。想要进行深拷贝,请将true作为第一个参数:$.extend(true, {}, a); - Reid
6
一个需要注意的细节:jQuery.extend(true, {}, obj); 会创建一个对象的复制品。但 jQuery.extend(true, obj, {}); 不会。 - worldsayshi
@worldsayshi:真希望我早点看到你的评论。这个问题困扰了我好几周。非常感谢。 - nicolas
1
太棒了,伙计们!正是我需要的! - curveball

36

8

对于我来说,使用jQuery的“parseJSON()”和“JSON.stringify()”更好地克隆对象。

$.ajax({
  url: 'ajax/test.html',
  dataType: 'json',
  success: function(data) {
    var objY = $.parseJSON(JSON.stringify(data));
    var objX = $.parseJSON(JSON.stringify(data));
  }
});

在objX和objY中克隆数据对象是两个不同的对象,您无需处理“按引用传递”的问题

谢谢!


1
你可以不使用jQuery来完成这个任务,使用内置的JSON.parse方法即可。 - MarkosyanArtur

7
另一种克隆对象的方法是:
newObj = JSON.parse(JSON.stringify(oldObj));

但是如果其中包含日期,就要小心了。在这种情况下,JSON.parse将返回date.toString()而不是日期本身。


3

以下是我如何复制元素的步骤:

首先,我准备了一个模板:

<div class="forms-container">
    <div class="form-template">
        First Name <input>
         .. a lot of other data ...
        Last Name <input>
     <div>
     <button onclick="add_another();">Add another!</button>
<div>

现在,让我们来看一下 JavaScript:
function add_another(){
    jQuery(".form-template").clone().appendTo(".forms-container");
}

2

尝试使用Immutable.js

jQuery主要处理DOM元素,可能不是最适合的工具。而Immutable.js是由Facebook创建的一个56kb(压缩后)的库。

// roughly implementing
import Immutable from 'immutable'
//
const oldObj = { foo: 'bar', bar: 'baz' }
// create a map from the oldObj and then convert it to JS Object
const newObj = Immutable.Map(oldObj).toJS()

这样,您实际上已经从旧对象 oldObj 克隆了 newObj。如果您没有一个 Map,那么我们需要先创建一个 Map。Map 就像一个蓝图,我们用它来创建 copies

参考资料:

主页 - Immutable

文档 - Immutable 文档

GitHub - Immutable@GitHub

祝好运。


1
如果您需要保留初始对象但需要使用新选项覆盖数据,则可以将多个对象传递给$.extend (jQuery),并在第一个选项上设置true:
var opts_default = {opt1: true, opt2: false};
var opts_new = {opt1: false};
var opts_final = $.extend(true, {}, opts_default, opts_new);

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接