我以为我掌握了原型继承,但现在在派生对象上设置对象属性是可行的。请考虑以下代码:
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“,其值分别为"Base”和“派生”(如预期的那样) 2)但是myBase.obj和myObj.obj指向了现在具有prop=值“派生”的同一个对象。
这是怎么回事?我已经了解到,在设置对象属性时,解释器不会沿着prototype链向下移动,而是在执行"set“的实例上创建属性(它为string属性执行此操作)。但是解释器如何处理对象属性的设置呢?为了找到目标,它一定是从链条上下来的。它是否在派生对象中创建了对该对象的新引用?
希望我能说清楚(当我读到这篇文章时,我对此表示怀疑,但我无法更好地解释),我非常感谢任何人能对此做出一些解释。
发布于 2014-06-08 12:29:24
我已经了解到,在设置对象属性时,解释器不会沿着原型链向下移动,而是在执行"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将对存储在该obj中的值设置prop。因为com_mtag.myObj本身没有这样的属性,所以它必须使用存储在com_mtag.myBase.obj上的对象来查找要设置prop的对象。
相反,请考虑使用prop属性创建一个新对象并将整个对象存储在com_mtag.myObj.obj中的可能性。
com_mtag.myObj.obj = { prop: "Derived" };没有创建这样的新对象,只存在原始原型obj对象。JavaScript引擎不会在myObj.obj上创建新对象;它将使用原型上的对象。
https://stackoverflow.com/questions/24105838
复制相似问题