2014-02-09 48 views
0

我正在尝试创建对象a的副本,而无需手动将其属性输入到对象b中。在这个代码中,b简单地指的是a。我想创建一个新版本的a,所以当我向b添加一个属性时,它通过a不可见。JavaScript:如何制作一个对象的副本?

var a = new Object(); // create an empty object 
var b = a;    // now b refers to the same object 
b.test = 1;   // add a new property to b 
alert(a.test);   // => 1: the new property is also visible through a 
a === b;    // => true: a and b refer to the same object 
+2

'存储a的值(b)应该是“将同一对象的引用赋值给'b'”。 – RobG

+1

你真的打算'a'是一个函数吗?您在该行的评论意味着其他情况。 –

+0

“b指向同一对象”意味着“向b添加新属性”等于“向a添加新属性”。 “ – leaf

回答

2

您有JavaScript对象和等号(= )运算符的工作时要小心。该运算符不会创建该对象的副本,而只会分配对原始内部对象的引用。

这意味着,你的情况,b店的值(S)的一个,但调用

var b = a; 

两个一个b点后内存中的同一个对象!因此,更改b的任何属性也会将它们更改为a(同样:它们在内部是相同的对象)。

要创建一个对象的副本你有它的每一个特性手动复制:

var a = {}; // create an empty object 
a.prop1 = 1; // set a property of this object 
var b = {}; // create another empty object 
b.prop1 = a.prop1; // copy all properties (in this case: only one) of a to b 
b.test = 1; // add a new property to b 
alert(a.test); // => undefined, as .test is only defined for b 
a === b; // => false, as a and b are different objects. 

一个优雅的解决克隆JS对象的问题可以在这里找到:How do I correctly clone a JavaScript object?

+0

*”'a'实际上不是一个对象“*它是!函数也是对象。 –

+0

你是对的!据此编辑。 – dominikus

3

在普通的JavaScript,你可以这样做:

var copy = JSON.parse(JSON.stringify(myObj)); 

参见:http://jsfiddle.net/kukiwon/AyKdL/

+1

这当然不适用于功能。 –

+0

@FelixKling,正确,但这个问题应该改变。 – Kukiwon

1

在你的例子中,“a”只是一个函数对象,你只是创建了额外的指针。

只需创建他们

var a1 = new a(); 
var b1 = new a(); 
a1.test = 1; 
b1.test = 2; 

a1 != b1 

优势的新实例使用一个函数作为类是利用Object.prototype中,继承和实例检查。如果你想只是一个数据存储,然后只需将其更改为通用对象

var a = {}; 
var b = {}; 
a.test = 1; 
b.test = 2; 

“的JavaScript好的部分”是绝对必要的

http://www.youtube.com/watch?v=hQVTIJBZook

http://www.amazon.com/JavaScript-Good-Parts-Douglas-Crockford/dp/0596517742

2

有关使用深层如何复制模式如下。 这是来自Stoyan Stefanov的“Javascript Patterns”。

function extendDeep(parent, child) { 
    var i, 
     toStr = Object.prototype.toString, 
     astr = "[object Array]"; 

    child = child || {}; 

    for (i in parent) { 
     if (parent.hasOwnProperty(i)) { 
      if (typeof parent[i] === "object") { 
       child[i] = (toStr.call(parent[i]) === astr) ? [] : {}; 
       extendDeep(parent[i], child[i]); 
      } else { 
       child[i] = parent[i]; 
      } 
     } 
    } 
    return child; 
} 
+1

if(parent.hasOwnProperty(i)&&!child.hasOwnProperty(i)){....}如果你不想覆盖属性是那里 – zloctb

相关问题