0

这里有一些例子。

// case 1:
var obj1 = {msg : 'Hello'};
var obj2 = obj1;
obj2.msg = "Hi!"; //overwrites
alert(obj1.msg); //=>'Hi!'

// case 2:
var obj1 = {msg : 'Hello'};
var obj2 = Object.create(obj1);
obj2.msg = "Hi!"; //does not overwrite
alert(obj1.msg); //=>'Hello'

// case 3:
var obj1 = {data: { msg : 'Hello'}}
var obj2 = Object.create(obj1);
obj2.data.msg = "Hi!"; //overwrites, Why?
alert(obj1.data.msg); //=>'Hi!'

我认为Object.create()只是让两者都指向同一个原型,而赋值使两个对象都指向同一个位置(不仅仅是原型)。 但是为什么在案例 3 中数据对象会被覆盖呢?

4

3 回答 3

6

因为Object.create()只创建一个浅拷贝,嵌套对象仍然被引用而不是深度拷贝,参见15.2.3.5 ( Object.create()) 和15.2.2.1 ( new Object())。

如果您想完全克隆一个对象,请查看如何正确克隆 JavaScript 对象?和类似的问题。

于 2013-03-09T08:02:16.197 回答
4

var obj2 = Object.create(obj1)创建一个以 obj1 作为其原型的空(!)对象。

obj2.msg = "Hi!"将属性 msg 添加(!)到 obj2。

obj2.data.msg = "Hi!"在 obj2 上查找属性数据,但 obj2 为空。所以它在 obj2 的原型上查找属性数据,它恰好是 obj1。然后它将 obj1.data 上的 msg 更改为“Hi”。

于 2013-03-09T11:39:31.607 回答
0

发生这种情况是因为 java 脚本设置和检索属性的方式。要获取属性,它会查找原型链,而将其设置在最本地的对象上。

在情况 2 中,这就是它不覆盖的原因。它将 msg 属性设置为 obj2。在情况 3 中,它在父对象中获取数据对象并在那里设置属性。因此它被覆盖。在情况 1 中,它们都在引用对同一个对象

于 2015-05-23T05:30:40.920 回答