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

Javascript 使用Object.create()和使用赋值运算符有什么区别?,javascript,ecmascript-5,prototypal-inheritance,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

这里有几个例子

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

因为
对象.create()
只创建一个浅拷贝,嵌套对象仍然被引用而没有被深度复制,请参见(
对象.create()
)和(
新对象()


如果你想完全克隆一个对象,请看一看和类似的问题。

var obj2=object.create(obj1)
以obj1为原型创建一个空(!)对象

obj2.msg=“Hi!”
将属性msg添加到obj2


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

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


在案例2中,这就是它不重写的原因。它在obj2处设置msg属性。在案例3中,它获取父对象中的数据对象并在那里设置属性。因此,它被重写。在案例1中,它们都引用同一个对象。

为了详细说明这一点,当您设置原型属性时,如果它是字符串或数字之类的简单值,它将在对象本身而不是原型上进行设置,但如果要修改现有对象或数组属性,则将更改原型上的属性。理解这种区别很重要,因为它对正确继承有影响;有关更多信息,请参阅。