简体   繁体   English

JavaScript深度JSON克隆

[英]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? 在下面的示例中,代码几乎可以正常工作,它无法进行深度克隆,因此在所有创建的对象中,Test.options。*无法克隆/复制。*是相同的引用,知道我做错了吗?

//* 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";
console.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

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). 我知道这不是一个完整的答案,但是请考虑仅在Mozilla引擎中才可以使用原型 (我假设您在这里使用Rhino)。

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. 这意味着以下代码在您的克隆结构中为true。

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. 请访问http://javascript.crockford.com/,它涵盖了许多对象创建机制并很好地描述了原型。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM