以后再次设置派生对象的属性时,从基对象继承的属性会发生什么情况?



这里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()是从对象派生xo因此它们处于对象o的原型中。

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

编辑代码在谷歌浏览器的控制台中运行,输出格式是从那里复制的

此行为在规范本身中有很好的文档记录

换句话说,首先检查直接提到的对象 这样的财产;如果该对象包含命名属性,则 引用所指的属性;如果该对象没有 包含命名属性,检查该对象的原型 下一个;等等

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

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

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

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

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

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

object_o's_property.a*object_o's_property.a在第一种情况下是 5 * 5。为什么?因为搜索从o对象开始,并将继续搜索,直到找到它或命null值(即原型链的末尾)。同样,将从o开始搜索,然后递归地protoproto,直到找到属性或命中null

最新更新