开发者

javascript deep json clone

I am trying to build small functions to simulate Class related functionalities (ok, I know about frameworks).

In the following example, the code almost work, it fails on deep cloning, somehow the Test.options.* fails to clone/copy, in all created objects options.* is the same reference, any idea what I have been doing wrong?

//* class lib *//
function clone(o) {
    var tmp = new o.constructor();
    tmp.__proto__ = o;
    return tmp;
};
var Class = function(o) {
    var tmp = new Function();
    tmp.prototype = clone(o);
    return tmp;
};
//*/

//* object schema *//
var Test = new Class({
    deep: "yes",
    options: {
        inside: true
    }
});
//*/

//* object Test 1 *//
var t1 = new Test();
console.log(t1.deep); // "yes"
t1.deep = "no";
consol开发者_JAVA百科e.log(t1.deep); // "no"
console.log(t1.options.inside); // true
t1.options.inside = false;
console.log(t1.options.inside); // false
//*/

//* object Test 2 *//
var t2 = new Test();
console.log(t2.deep); // "yes"
console.log(t2.options.inside); // should be true but I get false


Like this?

http://overset.org/2007/07/11/javascript-recursive-object-copy-deep-object-copy-pass-by-value/

As noted there, if you're using jQuery, you already have this functionality:

http://docs.jquery.com/Utilities/jQuery.extend


I know this is not a complete answer but consider that proto is only available in mozilla engines (I am assuming you are using Rhino here).

Logically your clone is actually wrong. You are not understanding prototypes here.

A prototype is an object to look up a property in if the parent of the prototype does not contain it (think about it that way). Which means that the following code IS true in your clone structure.

var t1 = new Test(); // test object created
var t2 = new Test(); // test object 2 created
t1.options.inside = false;
t2.options.inside; // false
t1.options.inside = true;
t1.options = { inside: false };
t1.options.inside; // false
t2.options.inside; // true

This is because options is a shared reference in the prototype. Prototype never clones, it only allows your object to define a property, and thus HIDING the prototype's value.

A true clone will do something like

for(var i in o) {
    clone[i] = clone(o[i]); // deep cloning here
    clone[i] = o[i]; // shallow cloning
}

This is of course simplified because there are issues with cloning dates, strings, etc. In general cloning is not a simple task.

Check out http://javascript.crockford.com/ it covers lots of object creation mechanisms and describes prototypes well.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜