Amit Amit - 2 months ago 8x
Javascript Question

JavaScript cloning a "class" instance

I have a class that goes like this:

function Element(){
this.changes = {};

Now I have an instance of this "Class" like so,
el = new Element()
. These instances are stored in an array, like

This array of elements is now stored in an object, which is then pushed in an array,

Now there are cases where I need a copy of one of the elements, so I would need to do something like,
var cloned = $.extend(true, {}, states[0])
. Here I assumed that we are cloning the first state.

The problem now is that what I get, the
is still pointing to the original instance. Thus any changes I am making to the cloned object, are changing the original too.

It's frustrating to be stuck on such a trivial problem...

Here is a fiddle I created to test it out:


$.extend is only cloning plain objects. If the object has a constructor then it is not cloned, but just copied.

From the $.extend source:

if ( jQuery.isPlainObject(copy) /* ... */) {
  // do the recursive $.extend call and clone the object                
} else if ( copy !== undefined ) {
  target[ name ] = copy;
  // ^^^^^ just copy

So $.extend() will call isPlainObject(el) which will return false, because el has an constructor and instead of cloning the el is copied. So states[1].elements[0] is the same object as states[0].elements[0] because it was not cloned.

If we modify your example from:

function Element(){
  this.changes = {};
var el = new Element();    // $.isPlainObject(el); <- false
// ...


var el = { changes: {} };  // $.isPlainObject(el); <- true
// ...

It will clone the el properly. See it HERE.