当稍后再次设置派生对象的属性时,从基础对象继承的属性会发生什么?

问题描述 投票:0回答:3

这里Object.create()用于继承。

JavaScript代码:

var x = {
  a: 5, 
  foo: function() {
    return this.a * this.a;
  }
};

var o = Object.create(x);

console.log('\'x\':', x);
console.log('Object \'o\':', o);
console.log('Property \'o.a\':', o.a);
console.log('Method \'o.foo()\':', o.foo());

o.a = 7;
console.log('-----After setting o.a directly-----');

console.log('Object \'o\':', o);
console.log('Property \'o.a\':', o.a);
console.log('Method \'o.foo()\':', o.foo());

上面代码的输出是:

'x': { a: 5, foo: [Function: foo] }
Object 'o': {}
              __proto__: 
                  a: 5
                  foo: ƒ ()
                  __proto__: Object

Property 'o.a': 5
Method 'o.foo()': 25

-----After setting o.a directly-----

Object 'o': {a: 7}
              a: 7
              __proto__: 
                a: 5
                foo: ƒ ()
                __proto__: Object

Property 'o.a': 7
Method 'o.foo()': 49

所以在第一个值a和函数foo()是从x对象派生到o对象所以他们在对象o的原型。

但后来当我在对象a中设置o的值时,该对象有一个新的属性a:7以及a:5仍然存在于对象o的原型中,奇怪的是功能foo()返回49(7 * 7)而不是25( 5 * 5)**,这怎么可能?

编辑:代码在谷歌Chrome控制台中运行,输出格式从那里复制

javascript inheritance prototype javascript-objects
3个回答
1
投票

这种行为在spec本身中有详细记载

换句话说,首先检查直接提到的对象的这种属性;如果该对象包含命名属性,那么该引用引用的属性;如果该对象不包含命名属性,则接下来检查该对象的原型;等等。

因此,当o没有自己的a属性时,则检查其原型是否存在该属性。

但是当a成为o的自有财产时,它被直接拿起而没有进入原型链。


1
投票

当您尝试访问对象中的属性时,它会尝试在该对象中查找,然后在原型链中查找。所以通过o.a的基本访问可以访问原型链中的属性a,直到o没有它自己的。

为对象设置原型时,prototypes属性仅用于读取访问。你可以阅读它们,但是当你试图改变它的值时,这里[[Set]]内部属性可以完成它的工作。它的工作是当你为一个不存在的属性赋值(自己的属性,而不是那些在原型链中的属性)时,它创建一个然后分配给它。因此,在您的情况下,您没有名为a的属性,因此它只创建一个新属性,使其为o拥有并分配给它。原型的属性现在仍可通过直接访问prototype访问。

在您使用this的功能中。当你调用o.foo()时,this引用的上下文是对象o,因为它有一个名为a且值为7的自有属性,所以在其中使用值7


1
投票

o.foo()意味着对象o从那里调用方法foo,这意味着this实际上是对象o

object_o's_property.a*object_o's_property.a在第一种情况下是5 * 5.为什么?因为搜索从o对象开始并将继续搜索,直到它找到它或命中null值aka,原型链的结束。再次,将开始搜索o然后其proto及其proto递归,直到找到属性或击中null

© www.soinside.com 2019 - 2024. All rights reserved.