我一直盯着这个答案,我无法绕过它:https://stackoverflow.com/a/23699009/3658800。
总结:
只有属性读取搜索原型链,而不是写入。所以当你设置
时myObject.prop = '123';
它不会查找链,但是当你设置
时myObject.myThing.prop = '123';
在写入操作中有一个微妙的读取,试图在写入其道具之前查找myThing。这就是为什么从子节点写入object.properties会获取父节点的对象。
我基本上要求有人详细说明这种“微妙的阅读”操作。首先评估myObject.myThing,返回对myThing对象的引用(然后设置其“prop”属性)?是否有一些我可以证实这一点的来源(Mozilla,Javascript源代码等)?
答案 0 :(得分:4)
在写入操作中有一个微妙的读取,试图在写入其prop之前查找myThing。这就是为什么从子节点写入object.properties会获取父节点的对象。
这不是一个“微妙”的阅读。这是一个经常阅读。
obj.prop1.prop2 = "foo"
被解释为(obj.prop1).prop2 = "foo"
。假设有虚构的read
和write
基元,它将作为
write(
read(obj, 'prop1'),
'prop2',
"foo")
如果这更清楚。换句话说,首先,来自prop1
的{{1}} 读取。咨询原型链是正常的读取。如果发现它不在实例上,而是在原型链上,则结果是原型上的obj
。
接下来,prop1
对prop2
生成的对象设置。如果恰好是原型上的obj.prop1
,则在原型上的prop1
上设置属性prop2
。如果在实例上找到prop1
,则会在该实例上的prop1
上设置属性prop2
。
这里没有任何改变,读取参考原型链的基本原理,写入总是在写入的对象上(不参考原型链)。
请注意,在原型上存在setter和getter时,此行为可能会有细微差别。
为避免让自己和他人混淆,最好避免在原型上保留数据。将原型视为专门或主要作为共享基于该原型创建的对象的方法的方法。理想情况下,使用原型来保存数据应该限制在实例之间共享的真正恒定数据。