在javascript中完全克隆一个对象

Tom*_*Tom 20 javascript jquery clone

我试图在javascript中完全克隆一个对象.我使用jquery知道以下解决方案:

var newObject = jQuery.extend({}, oldObject);
// Or
var newObject = jQuery.extend(true, {}, oldObject);
Run Code Online (Sandbox Code Playgroud)

但问题是,对象类型丢失了:

var MyClass = function(param1, param2) {
    alert(param1.a + param2.a);
};
var myObj = new MyClass({a: 1},{a: 2});
var myObjClone = jQuery.extend(true, {}, myObj);
alert(myObj instanceof MyClass);      // => true
alert(myObjClone instanceof MyClass); // => false
Run Code Online (Sandbox Code Playgroud)

是否有任何解决方案可以在第二个警报上实现?

Ste*_*ano 12

jQuery.extend不希望你使用instanceof运算符.它正在做一个光荣复杂的副本,而不是一个真正的克隆.循环使用元素是不够的.此外,调用构造函数不是最好的,因为你将失去你的参数.试试这个:

var MyClass = function(param1, param2) {
    alert(param1.a + param2.a);
    this.p1 = param1;
    this.p2 = param2;
};

function Clone() { }
function clone(obj) {
    Clone.prototype = obj;
    return new Clone();
}

var myObj = new MyClass({a: 1},{a: 2});
var myObjClone = clone(myObj);
alert(myObj instanceof MyClass);      // => true
alert(myObjClone instanceof MyClass); // => true
console.log(myObj);       //note they are
console.log(myObjClone)   //exactly the same
Run Code Online (Sandbox Code Playgroud)

请注意,由于您的原型现在指向原始(myObj),myObj的任何更改都将反映在myObjClone中.Javascript的原型继承有点棘手.您需要确保新对象具有正确的原型,因此需要正确的构造函数.

Admitadly,Javascript让我头疼.不过,我认为我正在从ECMAScript语言规范中读到这个:

13.2.2 [[Construct]]
当使用可能为空的参数列表调用Function对象F的[[Construct]]内部方法时,将执行以下步骤:

  1. 让obj成为新创建的本机ECMAScript对象.
  2. 按照8.12中的规定设置obj的所有内部方法.
  3. 将obj的[[Class]]内部属性设置为"Object".
  4. 将obj的[[Extensible]]内部属性设置为true.
  5. 让proto成为使用参数>"prototype"调用F的[[Get]]内部属性的值.
  6. 如果Type(proto)是Object,则将obj的[[Prototype]]内部属性设置为proto.
  7. 如果Type(proto)不是Object,则将obj的[[Prototype]]内部属性设置为>标准内置Object原型对象,如15.2.4中所述.
  8. 令result为调用F的[[Call]]内部属性的结果,提供> obj作为此值,并将传递给[[Construct]]的参数列表作为args.
  9. 如果Type(result)是Object,则返回结果.
  10. 返回obj.

这个人似乎比我更了解这个概念.K,我现在回到java,我游泳比我下沉:).