关于jquery:JavaScript克隆“类”实例

JavaScript cloning a “class” instance

本问题已经有最佳答案,请猛点这里访问。

我有一门课是这样的:

1
2
3
function Element(){
    this.changes = {};
}

现在我有一个这样的"类"实例,el = new Element()。这些实例存储在一个数组中,如elements.push(el)

这个元素数组现在存储在一个对象中,然后将该对象推入一个数组(states)。

现在有些情况下,我需要一个元素的副本,所以我需要做一些类似于var cloned = $.extend(true, {}, states[0])的事情。在这里,我假设我们正在克隆第一个状态。

现在的问题是,我所得到的,state[1].elements[0]仍然指向原始实例。因此,我对克隆对象所做的任何更改也会更改原始对象。

被困在这样一个小问题上真令人沮丧…

我创造了一把小提琴来测试它:http://jsfiddle.net/e6wlw/


$.extend只是克隆普通对象。如果对象有一个构造函数,那么它不是克隆的,而是复制的。

$.extend来源:

1
2
3
4
5
6
if ( jQuery.isPlainObject(copy) /* ... */) {
  // do the recursive $.extend call and clone the object                
} else if ( copy !== undefined ) {
  target[ name ] = copy;
  // ^^^^^ just copy
}

因此,$.extend()将调用isPlainObject(el),返回false,因为el有一个构造函数,而不是复制el。因此,states[1].elements[0]states[0].elements[0]是同一对象,因为它不是克隆的。

如果我们修改您的示例:

1
2
3
4
5
function Element(){
  this.changes = {};
}
var el = new Element();    // $.isPlainObject(el); <- false
// ...

进入:

1
2
var el = { changes: {} };  // $.isPlainObject(el); <- true
// ...

它将正确克隆el。看这儿。


您可以使用http://documentcloud.github.com/underline/克隆来克隆对象,例如:

1
var cloned = _.clone(states[0]);