我认为我掌握了原型继承,但现在在派生对象上设置对象属性起作用。 请考虑以下代码:
var com_mtag = {};
com_mtag.start = function(){
// creating myBase and setting a string property and an object-property
// both have a "prop" property set to "Base"
com_mtag.myBase = {};
com_mtag.myBase.prop = "Base";
com_mtag.myBase.obj = {prop: "Base"};
// Now derive myObj from myBase...
com_mtag.myObj = Object.create(com_mtag.myBase);
// modifying prop and obj.prop via the derived object
com_mtag.myObj.prop = "Derived";
com_mtag.myObj.obj.prop = "Derived";
};
结果如下: 1)myBase和myObj都有一个属性" prop"与价值观#34; Base"和"派生"分别(如预期) 2)但myBase.obj和myObj.obj指向同一个对象,该对象现在具有值prop =" Derived"
这是如何工作的?我已经了解到,在设置对象属性时,解释器不会沿着原型链向下,而是在实例上创建属性,其中" set"执行了(它为字符串属性执行此操作)。 但是解释器如何处理设置对象属性?它必须沿着链条向下移动以便找到对象。它是否在派生对象中创建了对此对象的新引用?
希望我清楚自己(当我读到这篇文章时我怀疑但我无法更好地解释),我非常感谢任何人对此有所了解。
答案 0 :(得分:1)
我已经了解到,在设置对象属性时,解释器不会沿着原型链向下移动,而是在实例上创建属性,其中" set"已经完成了
是的,这是真的,但访问链com_mtag.myObj.obj
中的每个属性都是读取属性值,而不是设置它们。只有最后的.prop
实际上设置了任何内容。
当您在对象上设置属性时,您正在设置对象的拥有属性(我们说"拥有"属性以区别于继承的属性原型属性),它使用相同的名称隐藏任何原型属性。这就是为什么您可以使用新值隐藏继承的com_mtag.myObj.prop
:com_mtag.myObj
获取其自己的 prop
属性。
但是,使用com_mtag.myObj.obj.prop
,您可以设置作为myBase
原型的属性存在的对象的属性。在这种情况下,com_mtag.myObj
不会获得自己的obj
广告,因为您没有设置obj
;你只是在读它。
com_mtag.myObj
没有自己的obj
属性,因此com_mtag.myObj.obj
必须引用存储在原型obj
属性中的值,即,com_mtag.myBase.obj
。因此,com_mtag.myObj.obj.prop
引用该对象上的prop
属性。
如果您已为com_mtag.myObj
提供了obj
个属性,那么com_mtag.myObj.obj.prop
会将prop
设置为obj
中存储的值。由于com_mtag.myObj
没有自己的此类属性,因此必须使用com_mtag.myBase.obj
中存储的对象来查找要设置prop
的对象。
考虑创建一个具有prop
属性的新对象,并将整个对象存储在com_mtag.myObj.obj
中的可能性:
com_mtag.myObj.obj = { prop: "Derived" };
如果不创建这样的新对象,则只存在原始原型obj
对象。 JavaScript引擎不会在myObj.obj
上创建新对象;它将使用原型上的那个。