Javascript cloning objects

I haven’t posted for a while as I’ve been busy but I thought I’d post about object cloning because it’s a useful tip and can be used in many situations like browser hacking or general web development. I posted this to the sla.ckers forum a while ago but in case you missed it here goes….

When cloning a object in Javascript many of the examples I found used for(i in..) to traverse the properties and copy each of them. There is a nicer way to do this using the uneval function like this:-

obj={a:1,a:2}
function clone(o) {
 return eval(uneval(o));
}
obj2 = clone(obj);
obj2.a=0;
alert(obj.a);
alert(obj2.a);

Giorgio Maone pointed out that it would be nice to prototype the code to make it easier to implement:-

Object.prototype.clone = function() {
  return eval(uneval(this));
}
alert("test".clone());
alert((3).clone());
alert(clone.clone());
Share and Enjoy: These icons link to social bookmarking sites where readers can share and discover new web pages.
  • Digg
  • del.icio.us
  • Slashdot
  • StumbleUpon

Comments 7

  1. Hakan Bilgin wrote:

    Hi Gareth,
    Great tips! Unfortunately, if the object contains a reference to an HTML or XML element, those references is not cloned (of course). Which in turn makes this solution a little inadequate.

    Yet, thanx for the trick!

    Posted 10 Apr 2008 at 9:54 am
  2. pdp wrote:

    of course that works with FF and a few other browsers only. The more universal way of doing the same is exactly what I used in CoreAPI: http://www.gnucitizen.org/projects/coreapi/

    CoreAPI.clone = function (o) {
    function c(o) {
    for (var i in o) {
    this[i] = o[i];
    }
    }

    return new c(o);
    };

    Posted 10 Apr 2008 at 11:05 am
  3. Gareth Heyes wrote:

    @pdp

    Damn I thought it worked in IE7 ah well neat trick anyways

    Posted 10 Apr 2008 at 12:43 pm
  4. kourge wrote:

    It is bad practice to mingle with Object.prototype because it messes up property enumeration. Just google “Object.prototype is verboten” and a zillion arguments will appear. The Prototype JavaScript library once did this in 1.3 - with bad results.
    The fix is to instead tack methods on to the global Object. For example:
    Object.clone = function(object) { return eval(uneval(object)); };

    Posted 10 Apr 2008 at 5:08 pm
  5. Gareth Heyes wrote:

    @kourge

    Nice tip and good point

    Posted 10 Apr 2008 at 5:19 pm
  6. kymin wrote:

    Have you not about c & c++ ’s book ?
    Post my E-mail,thank you

    Posted 20 Apr 2008 at 6:38 pm
  7. Mikael Grave wrote:

    Your eval/uneval idea inspired me a cross-browser solution for those using YUI:

    function clone = function( obj ) {
    return YAHOO.lang.JSON.parse( YAHOO.lang.JSON.stringify( obj ) );
    }

    Tested fine with IE6 and FF2. Especially convenient for cloning arrays, hashs of arrays, arrays of hashs, etc.

    Not sure about the performances. Might slow down your app if used to massively clone objects…

    Posted 09 May 2008 at 5:29 pm

Post a Comment

Your email is never published nor shared. Required fields are marked *

Comment spam protected by SpamBam