在javascript中设置父对象与子对象的属性时的混淆

在javascript中设置父对象与子对象的属性时的混淆,javascript,Javascript,假设我们有这样一个代码示例: var obj1={ prop:1 }; var obj2=Object.create(obj1); obj2.prop=2; console.log(obj1.prop); 在这里,我们将输出为1,因为在子对象obj2中,属性prop将被隐藏。但是,当我这样做时: var obj1={ prop:{subProp:1} }; var obj2=Object.create(obj1); obj2.prop.subProp=2; console.log(obj1.p

假设我们有这样一个代码示例:

var obj1={ prop:1 };
var obj2=Object.create(obj1);
obj2.prop=2;
console.log(obj1.prop);
在这里,我们将输出为
1
,因为在子对象
obj2
中,属性
prop
将被隐藏。但是,当我这样做时:

var obj1={ prop:{subProp:1} };
var obj2=Object.create(obj1);
obj2.prop.subProp=2;
console.log(obj1.prop.subProp);
在这里,我惊奇地发现输出是
2
,尽管子对象上的值正在更改。为什么这里没有发生可变阴影。换句话说,为什么没有在
obj2
上创建名为
prop
的新属性,为什么父对象(
obj1
)的
prop
在这里被操作

编辑:如果我执行以下操作

var obj1={ prop:1 };
var obj2=Object.create(obj1);
var isPresent=obj2.hasOwnProperty('prop');
console.log(isPresent);
这里的输出将为false。然而:

var obj1={ prop:1 };
var obj2=Object.create(obj1);
var isPresent=obj2.hasOwnProperty('prop');
console.log(isPresent);
obj2.prop=2;
isPresent=obj2.hasOwnProperty('prop');
console.log(isPresent);

正如您在第
obj2.prop=2行之后看到的,输出为true。这也让我困惑。

这是因为当您创建
obj2
时,没有任何属性被复制,但是
obj2
的原型变成了
obj1
。这意味着在读取时,引擎在整个原型链中查找属性,而在写入时,您只需写入对象

当您执行
obj2.prop=2
时,您直接向
obj2
写入数据,但当您执行
obj2.prop.subop=2
时,您首先要求引擎读取
obj2.prop
,然后向该对象写入一些值


在第二个示例中,您从未直接写入到
obj2
,因此
obj2
仍然是“空的”(您可以按照注释中的建议,在每个示例之后使用
obj2.hasOwnProperty('prop')

,但是在设置obj2.prop=2之前添加此行obj2.hasOwnProperty('prop');在第一种情况下,我得到的答案是假的。但这是否意味着obj2中不存在prop?嗯,我误解了这个问题。您完全正确,我完全编辑了答案以更正此错误。@KiranYallabandi您可能会发现JavaScript原型继承的快速介绍非常有用。@Clement Prevost感谢您的澄清。目前,我指的是“you not know JS”系列书籍,其中提到每当发生对象查找时,都会使用[[get]],而对于对象分配,则使用[[put]]。你能不能给我一个网站的链接,在那里我的问题的解决方案是用这些术语解释的?好吧,这是一个非常具体的要求,但我不知道这些操作的命名方法,所以不幸的是,你必须适应作者的偏好。你可能会觉得有用。