使用Object.create()和使用赋值运算符有什么区别?

时间:2013-03-09 07:57:05

标签: javascript ecmascript-5 prototypal-inheritance

以下是一些例子。

// 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中数据对象被覆盖?

3 个答案:

答案 0 :(得分:6)

由于Object.create()仅创建浅层副本,嵌套对象仍会被引用而不会被深深复制,请参阅15.2.3.5Object.create())和15.2.2.1new Object() )。

如果你想完全克隆一个对象,请查看How do I correctly clone a JavaScript object?和类似的问题。

答案 1 :(得分:4)

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

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

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

答案 2 :(得分:0)

这是因为java脚本设置和检索属性的方式。为了获取属性,它查找原型链,同时设置它设置在最本地对象。

在案例2中,这就是它没有覆盖的原因。它将msg属性设置为obj2.In case 3它在父对象中获取数据对象并在那里设置属性.Hence它被覆盖。在案例1中它们都是指同一个对象