此处 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)**,这怎么可能?
编辑:代码在Google Chrome控制台中运行,输出格式从那里复制
答案 0 :(得分:1)
当您尝试访问对象中的属性时,它会尝试在该对象中查找,然后在原型链中查找。因此,通过o.a
进行基本访问可以访问原型链中的属性a
,直到o
没有它为止。
为对象设置原型时,原型属性仅用于 读取访问 。您可以阅读它们,但是当您尝试更改它的值时,此处 [[Set]] 内部属性可以完成其工作。它的工作是当你为一个不存在的属性(自己的属性,而不是那些在原型链中的属性)赋值时,它创建一个然后分配给它。因此,在您的情况下,您没有名称为a
的自有属性,因此它只创建一个新属性,使其为o
拥有并分配给它。现在,只有直接访问prototype
在您使用this
的功能中。当您致电o.foo()
时,this
引用的上下文是对象o
,因为它有一个名为a
且值为7
的自有属性,在其中使用了值7
。
答案 1 :(得分:1)
o.foo()
表示对象o
从那里调用方法foo
这意味着this
实际上是对象o
。
object_o's_property.a*object_o's_property.a
在第一种情况下是5 * 5.为什么?因为搜索从o
对象开始,并将继续搜索,直到找到它或命中null
值,即原型链的末尾。再次,将从o
然后以proto
及其proto
递归开始搜索,直到找到属性或点击null
。
答案 2 :(得分:1)
spec本身
中详细记录了此行为换句话说,首先检查直接提到的对象 这样的财产;如果该对象包含命名属性,即 引用所指的财产; 如果该对象没有 包含命名属性,检查该对象的原型 下一个;等等。
所以,当o
没有自己的a
属性时,检查其原型是否存在属性。
但当a
成为o
的自有属性时,直接获取它而不进入其原型链。