78

The below first logs 0, and then logs 1. How do I store a copy of the object, rather than a reference to it?

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

7 Answers 7

154

To clone an object in jQuery:

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

NOTE: The above is a shallow copy: any nested objects or arrays will be copied by reference - meaning any changes you make to vi.nextSegment.obj[prop] will be reflected in vi.details.obj[prop]. If you want a completely new object which is completely separate from the original, you will need to do a deep copy (pass true as the first parameter):

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

To read up more on extend, see here.

Sign up to request clarification or add additional context in comments.

4 Comments

That isn't a deep copy. var a = {b: [1, 2]}; $.extend({}, a).b[0] = 'test'; and a.b[0] will be changed to 'test'. To do a deep copy, put true as the first argument: $.extend(true, {}, a);
One gothcha that just got me: jQuery.extend(true, {}, obj); will create a copy. jQuery.extend(true, obj, {}); will not.
@worldsayshi : I wish I saw your comment sooner. Having headaches on this for weeks. Thanks a lot.
brilliant, guys! Just what I needed!
37

Take a look at the post: What is the most efficient way to clone a javascript object

As per John Resig's answer:

// Shallow copy
var newObject = jQuery.extend({}, oldObject);

// Deep copy
var newObject = jQuery.extend(true, {}, oldObject);

More information can be found in the jQuery documentation.

Comments

8

This worked better for me cloning an object using jQuery "parseJSON()" and "JSON.stringify()"

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

Cloning data object in objX & objY are two different object, you do no have to mess up with the "by reference" problem

Gracias!

1 Comment

you could do this without jquery use JSON.parse built-in method
8

Another way to clone object is

newObj = JSON.parse(JSON.stringify(oldObj));

But be careful if it's contains dates. JSON.parse will return date.toString() instead of date in that case.

Comments

3

This is how I copy elements several times:

First I have a template:

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

Now, the JavaScript:

function add_another(){
    jQuery(".form-template").clone().appendTo(".forms-container");
}

Comments

2

Try Immutable.js :

Since jQuery mostly deals with DOM Elements, it may not be the right tool for the job. Immutable.js is a 56 kb (minified) library created by 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()

This way you would have effectively cloned newObj from oldObj. Basically, if you don't have a Map already, then we need to create a Map first. Map is like a blue-print that we work with to create copies.

References :

Home - Immutable

Docs - Immutable Docs

GitHub - Immutable@GitHub

Good Luck.

Comments

1

If you need to keep you initial object but need to override your data with your new options, you can pass multiple objects to $.extend (jQuery) with true on first option:

var opts_default = {opt1: true, opt2: false};
var opts_new = {opt1: false};
var opts_final = $.extend(true, {}, opts_default, opts_new);

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.