这里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控制台中运行,输出格式从那里复制
这种行为在spec本身中有详细记载
换句话说,首先检查直接提到的对象的这种属性;如果该对象包含命名属性,那么该引用引用的属性;如果该对象不包含命名属性,则接下来检查该对象的原型;等等。
因此,当o
没有自己的a
属性时,则检查其原型是否存在该属性。
但是当a
成为o
的自有财产时,它被直接拿起而没有进入原型链。
当您尝试访问对象中的属性时,它会尝试在该对象中查找,然后在原型链中查找。所以通过o.a
的基本访问可以访问原型链中的属性a
,直到o
没有它自己的。
为对象设置原型时,prototypes属性仅用于读取访问。你可以阅读它们,但是当你试图改变它的值时,这里[[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
值aka,原型链的结束。再次,将开始搜索o
然后其proto
及其proto
递归,直到找到属性或击中null
。