javascript深层json克隆

javascript深层json克隆,javascript,Javascript,我试图构建一些小函数来模拟与类相关的功能(好的,我知道框架) 在下面的示例中,代码几乎正常工作,深度克隆失败,不知何故Test.options.*未能克隆/复制,在所有创建的对象选项中。*是相同的引用,知道我做错了什么吗 //* class lib *// function clone(o) { var tmp = new o.constructor(); tmp.__proto__ = o; return tmp; }; var Class = function(o)

我试图构建一些小函数来模拟与类相关的功能(好的,我知道框架)

在下面的示例中,代码几乎正常工作,深度克隆失败,不知何故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
像这样

如前所述,如果您使用jQuery,您已经具备了以下功能:


< P>我知道这不是一个完整的答案,但是考虑到<强> PROTO <强>只能在Mozilla引擎中使用(我假设你在这里使用犀牛)。 从逻辑上讲,你的克隆人实际上是错的。你不理解这里的原型

如果原型的父对象不包含属性,则原型是要在其中查找属性的对象(这样考虑)。这意味着以下代码在克隆结构中是正确的

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
这是因为选项是原型中的共享引用。Prototype从不克隆,它只允许对象定义属性,从而隐藏Prototype的值

一个真正的克隆人会做这样的事情

for(var i in o) {
    clone[i] = clone(o[i]); // deep cloning here
    clone[i] = o[i]; // shallow cloning
}
这当然是简化的,因为克隆日期、字符串等方面存在问题。一般来说,克隆不是一项简单的任务


查看它,它涵盖了许多对象创建机制,并很好地描述了原型。

您甚至可以通过将jQuery扩展函数从jQuery中拉出来使用它。它只引用jQuery中的两个非常小的其他函数。然后您可以执行
obj_new=extend({},obj_old)
,jQuery extend函数肯定是交叉浏览器。您不需要运行深度扩展吗?深度克隆应等同于在对象上运行“新建”。一个没有共享子对象的全新实例。感谢您的评论,我已将克隆函数增强为
函数clone(o){if(o==null | | | typeof o!=“object”){return o;}var tmp=new o.constructor();for(o中的var key){tmp[key]=clone(o[key])}return tmp;}它仍然不起作用,但是如果我做
vart1=clone(newtest()),我从这段代码中得到了一些有趣的东西而不是
var t1=new Test()它可以工作,但我不想像这样包装我的代码。在注释中,您可以用back`(backtick)字符将代码格式化。它也适用于问答。
构造函数
也不是标准/跨浏览器。而且它也不符合您的想法,应该始终避免使用。@bobince,
constructor
如何不跨浏览器?从来没有问题。我总是在调用我父母的构造函数时使用它。您可能指的是,许多自制类系统在链接原型后忘记正确重置构造函数