tags:

views:

131

answers:

5

This is another way to create a javascript object (using object literal notation instead of function):

user = {
  name: "Foo",
  email: "[email protected]"
}

Is there a way to clone this object or is it a singleton?

A: 

Most of the javascript frameworks have good support for object cloning.

var a= {'key':'value'};
var b= jQuery.extend( true, {}, a );
Jonathan Vanasco
A: 

You can use JSON object (present in modern browsers):

var user = {name: "Foo", email: "[email protected]" } 
var user2 = JSON.parse(JSON.stringify(user))

user2.name = "Bar";
alert(user.name + " " + user2.name); // Foo Bar

See in jsfiddle.


EDIT

If you need this in older browsers, see http://www.json.org/js.html.

Topera
hmm... not going to downvote you but this is just silly, in my opinion. first of all, if you are going to use JSON, you WILL need to include json2.js in your page because there are still current browsers without native json and there will be in common use those that are not current for some time. Either write or borrow an extend implementation or include a library that has one.
Sky Sanders
I'm just giving another way to do this. If a site already have json2.js, it works.
Topera
A: 

I like to use this:

if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
    return new F();
    };
}

then any object I want to clone can be done as:

user = {
    name: "Foo",
    email: "[email protected]"
};
var user2 = Object.create(user);

As shown in (or similar to) JavaScript The Good Parts

Chris J
You shouldn't do this; see [Kangax' answer](http://stackoverflow.com/questions/3075308/what-modernizer-scripts-exist-for-the-new-ecmascript-5-functions/3075818#3075818)
Marcel Korpel
@Marcel Thanks for pointing that out. I'll leave my answer as is and recommend Kangax' explanation as a good read.
Chris J
@Marcel/Chris +1; Kangax's answer is only that create doesn't take two properties everywhere. My feeling is if everyone used this method, then it would force vendors to comply to standards. I didn't use FF initially because it didn't display everything correctly, now the web got smarter and FF has made modifications to work better in quirksmode. The same will be true if programmers confine to standards and push the browsers that accept them.
vol7ron
Would be good if Javascript could provide an easy way to clone objects
never_had_a_name
A: 

Updated:

   Object.prototype.clone = function clone(a) {
                               a=a||this;
                               var b = {};
                               for(var p in a) {
                                  if(typeof(a[p])==="object"){b[p]=clone(a[p]);}
                                  else                       {b[p]=a[p];}
                               }
                               return b;
                            };

   var foo = {
        name:  "Foo"
      , email: "[email protected]"
      , obj:   {a:"A",b:"B"}
   }

   var bar   = foo.clone();
   bar.name  = "Bar";
   bar.obj.b = "C";


   console.dir(foo);
   console.dir(bar);
vol7ron
no no no... never mess with Object.prototype, you'll break everything :P
no
that is incorrect, unless you're one of the drones that use `JQuery`, then never mess with anything and forget how to do anything.
vol7ron
Don't get upset. I generally avoid jQuery. Two things, though... 1, this isn't a clone, it's a copy. The name 'cloning' is associated with this sort of technique: http://oranlooney.com/functional-javascript/
no
2, don't mess with built-ins like Object and Array, not because of jQuery, but because someone will forget to use hasOwnProperty when iterating objects using `in` and suddenly they'll have extra properties in there, because another developer modified built-ins without them knowing.
no
[@no:](http://stackoverflow.com/users/331032/no) You make a valid point to remember, but I do not consider that good enough to essentially say "don't mess with prototype".
vol7ron
@vol7ron: okay, why don't you log in under some more accounts and upvote/downvote stuff until the numbers suit your fancy :)
no
@no: nope, wrong again. you're batting 0
vol7ron
All negatives and yet this is still the best answer.
vol7ron
+1  A: 

Try this:

var clone = (function(){ 
  return function (obj) { Clone.prototype=obj; return new Clone() };
  function Clone(){}
}());

Here's what's going on.

  • Clone is a dummy constructor.
  • We assign the object we want to clone to the Clone constructor's prototype.
  • We call Clone using 'new', so the constructed object has the original object as its constructor's prototype aka (non-standard) __proto__.

The cloned object will share all the properties of the original object without any copies of anything being made. If properties of the cloned object are assigned new values, they won't interfere with the original object. And no tampering of built-ins is required.

Keep in mind that an object property of the newly-created object will refer to the same object as the eponymous property of the cloned object. Assigning a new value to a property of the clone won't interfere with the original, but assigning values to the clone's object properties will.


Try this in chrome or firebug console:

var user = {
  name: "Foo",
  email: "[email protected]"
}

var clonedUser = clone(user);

console.dir(clonedUser);

A detailed explanation of this cloning technique can be found here.

no
`user={name:"",email:"",obj:{a:"A"}}; clonedUser=clone(user);`, `clonedUser.obj.a="B";` you'll find `user.obj.a == "B"`
vol7ron
This looks really similar to Chris J's answer too.
vol7ron
vol7ron: yes, because user.obj and clonedUser.obj refer to the same object. Assigning a new value to newUser's `obj` property will not exhibit this behavior. The request was for a clone, not a copy, and not a deep copy. See the link at the end of my answer.
no
@no: very good, if you edit the answer, I'll remove my downvote :) That is correct, but there is a big distinction in the article's definition of the programmatic `clone` and the vernacular definition of a clone.
vol7ron
Still article definition `A` cloned is `B`. `A` makes changes to property, `B` sees it. `B` makes changes to property, `A` doesn't give a ----. In your example, they would both share a nested object. If `B` makes changes to that object's property, `A` should not see the change. In all, cloning is discouraged, deep copying is encouraged.
vol7ron
Why not..... :)
no
Nah, clone B won't see changes to properties of original object A after the clone is made... try it and see for yourself. Unless you mean changes to properties of an object property shared by the clone and the original, of course.
no
The later, where a property already existed of the nested object. Changes of that property will be seen in the superclass. Even adding a property to that internal object is seen in both.
vol7ron
Yes, this is the desired behavior for a shallow operation like this. A deep clone function could easily be made if required. Again, the question asked for a clone, not a copy, a deep copy, or a deep clone.
no
I'm really curious what **ajsie** really wanted, my guess is a deep copy.
vol7ron
@vol7ron. I wasn't clear in my post what I meant, didn't know there was shallow and deep copy/clone. Is copy and clone the same thing btw? However, I'm looking for a way to make identical copies, that is to say deep copy I guess, or deep clone =) Does that answer still stand?
never_had_a_name
No, I suspected you'd want a complete copy; you'd want my solution, despite all the flame-war downvotes
vol7ron