克隆一个JavaScript对象?

Cloning a JavaScript object?

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

Possible Duplicate:
How to clone js object?

这是创建JavaScript对象的另一种方法(使用对象文字符号而不是函数):

1
2
3
4
user = {
  name:"Foo",
  email:"[email protected]"
}

有克隆这个对象的方法吗?还是它是单例的?


试试这个:

1
2
3
4
var clone = (function(){
  return function (obj) { Clone.prototype=obj; return new Clone() };
  function Clone(){}
}());

这是发生的事情。

  • 克隆是一个虚拟构造函数。
  • 我们将要克隆的对象分配给克隆构造函数的原型。
  • 我们使用"new"来调用克隆,因此构造的对象将原始对象作为其构造函数的原型aka(非标准)__proto__

克隆的对象将共享原始对象的所有属性,而不复制任何内容。如果克隆对象的属性被分配了新值,它们将不会干扰原始对象。而且不需要篡改内置组件。

请记住,新创建对象的对象属性将引用与克隆对象同名的属性相同的对象。将新值赋给克隆的属性不会干扰原始值,但将值赋给克隆的对象属性会。

在Chrome或Firebug控制台中尝试此操作:

1
2
3
4
5
6
7
8
var user = {
  name:"Foo",
  email:"[email protected]"
}

var clonedUser = clone(user);

console.dir(clonedUser);

这里可以找到这种克隆技术的详细解释。


您可以使用json对象(在现代浏览器中存在):

1
2
3
4
5
var user = {name:"Foo", email:"[email protected]" }
var user2 = JSON.parse(JSON.stringify(user))

user2.name ="Bar";
alert(user.name +"" + user2.name); // Foo Bar

请参见jsFiddle中的。

编辑

如果在旧的浏览器中需要,请参阅http://www.json.org/js.html。


我喜欢用这个:

1
2
3
4
5
6
7
if (typeof Object.create !== 'function') {
    Object.create = function (o) {
        var F = function () {};
        F.prototype = o;
    return new F();
    };
}

然后,我要克隆的任何对象都可以执行以下操作:

1
2
3
4
5
user = {
    name:"Foo",
    email:"[email protected]"
};
var user2 = Object.create(user);

如(或类似)javascript所示,好的部分


大多数JavaScript框架都支持对象克隆。

1
2
var a= {'key':'value'};
var b= jQuery.extend( true, {}, a );


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
Object.prototype.clone = function clone(obj) {
                           obj = obj || this;
                           var new_obj  = {};

                           for( var p in obj ) {
                             if ( obj.hasOwnProperty(p) ) {
                               if( obj[p] !== null && typeof(obj[p]) ==="object" ) {
                                 new_obj[p] = clone( obj[p] );
                               }
                               else {
                                 new_obj[p] = obj[p];
                               }
                             }
                           }

                           return new_obj;
                         };


/* Example */
var foo = {
     name: "Foo"
   , email:"[email protected]"
   , obj:   {a:"A",b:"B"}
};

var bar   = foo.clone();
bar.name  ="Bar";
bar.obj.b ="C";


// foo and bar should have a different 'name'
// foo and bar should retain the same email
// foo and bar should have different values for <foo/bar>['obj']['b']
// foo and bar should have the same values for <foo/bar>['obj']['a']
console.dir(foo);
console.dir(bar);