0

Here is my function which I am using to override the clone property of an object to create a new copy of the object not only the reference.

Object.prototype.clone = function () {
    var newObj = (this instanceof Array) ? [] : {};
    for (i in this)
    {
        if (i == 'clone') continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } else
            newObj[i] = this[i]
    }
    return newObj;
}

I have also added few properties to the window object.

Edit

Actually I am using seeveral libraries in my code. When I run this method without these libraries, it works fine. But with these libraries it gives this error. It is possible they have provided their own implementation of clone.

Now when I call this method I get the Maximum call stack size exceeded.

Any Help? Thank you

me_digvijay
  • 5,374
  • 9
  • 46
  • 83
  • Are you sure you don't have a circular reference somewhere in the object you are cloning? – Stefan Haustein May 27 '13 at 07:40
  • Because `clone` itself now will be recursively cloned... Check out [this link](http://stackoverflow.com/questions/122102/most-efficient-way-to-clone-an-object) before you move on. – Passerby May 27 '13 at 07:41
  • @Passerby no, that's not the problem! – Niccolò Campolungo May 27 '13 at 07:49
  • this seems to work fine http://jsfiddle.net/48syJ/ – mihai May 27 '13 at 07:50
  • @mihai try to clone an empty array – Niccolò Campolungo May 27 '13 at 07:51
  • @StefanHaustein: Actually I am using seeveral libraries in my code. When I run this method without these libraries, it works fine. But with these libraries it gives this error. It is possible they have provided their own implementation of clone. – me_digvijay May 27 '13 at 08:10
  • @StefanHaustein: I think I have a circular reference with the `this` keyword, which I cannot change. – me_digvijay May 27 '13 at 08:22
  • I'd add a console log statement to see where exactly the circle stems from. To check if any particular object has "suspicious" properties (that clone would see) I used Object.prototype.lp = function() { for (var p in this) {console.log(p);}} – Stefan Haustein May 27 '13 at 18:28
  • @StefanHaustein: I found the reason for the error. Actually the `window` object was causing the problem because the clone property was being applied to that also and since the all the objects were insied the `window` object so, I think that was creating the circular path and causing the problem. Thanks for your help and suggestion. Thank you. – me_digvijay May 27 '13 at 20:06

1 Answers1

0

Trying your method on a normal Object {} works fine, the issue comes when used with an Array []

I am not completely sure this is what you are looking for, but it solved the problem:

Object.prototype.clone = function () {
    if (this instanceof Array) return this.slice(0);
    var newObj = {};
    for (var i in this) {
        if (i == 'clone') continue;
        if (this[i] && typeof this[i] == "object") {
            newObj[i] = this[i].clone();
        } else newObj[i] = this[i];
    }
    return newObj;
};

If your Object is an instance of Array then cloning it in that way is not necessary, and I believe you can return it and stop the function. See this JSFiddle.

Niccolò Campolungo
  • 11,824
  • 4
  • 32
  • 39
  • Arrays are also passed by reference, so it's still worth to copy: http://jsfiddle.net/nzZCY/1/ – Passerby May 27 '13 at 07:58
  • Sorry but it didn't work for me. Still giving the same error. – me_digvijay May 27 '13 at 08:15
  • @Passerby you're right, I edited it, with `.slice(0)` works like a charm. – Niccolò Campolungo May 27 '13 at 08:17
  • @DigvijayYadav yes it is possible that is a problem of conflicting code, we can't do so much with that type of issue... – Niccolò Campolungo May 27 '13 at 08:22
  • @LightStyle `.slice(0)` still have pitfalls: http://jsfiddle.net/nzZCY/3/ Object copying in JS is simply messy. – Passerby May 27 '13 at 08:29
  • @LightStyle Check out the fiddle carefully. I logged `b`, tempered (special part of) `a`, logged `b` again, and `b` is also tempered. – Passerby May 27 '13 at 08:31
  • @LightStyle: I fixed the problem by making one change in my code. Actually somehow the `clone` method was being applied to the `window` object also. So I put a check for not not including the `window` object and it worked. Thanks to all for all your help. – me_digvijay May 27 '13 at 11:43
  • Btw: The main issue with slice here is that it doesn't apply clone to the contents of the array. – Stefan Haustein May 27 '13 at 21:11