在JavaScript中克隆对象


70

以下内容首先记录0,然后记录1。如何存储对象的副本,而不是对其的引用?

debug.log(vi.details.segment);
vi.nextSegment = vi.details;
vi.nextSegment.segment++;
debug.log(vi.details.segment);

Answers:


139

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

要阅读更多扩展内容,请参见此处。


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 2014年

1
大家好!正是我所需要的!
曲线球


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


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 Elements,因此它可能不是正确的工具。 Immutable.js是由56 kb (minified)创建的库Facebook

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

这样,您将可以有效地newObj从克隆oldObj。基本上,如果您还没有Map,那么我们需要创建一个Map。Map就像blue-print我们一起创建的地图copies

参考文献:

家- 不可变

文件- 不可变文件

GitHub- 不可变@GitHub

祝好运。


0

如果需要保留初始对象,但需要使用新选项覆盖数据,则可以将多个对象传递给$ .extend(jQuery),第一个选项为true:

var opts_default = {opt1: true, opt2: false};
var opts_new = {opt1: false};
var opts_final = $.extend(true, {}, opts_default, opts_new);
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.