问题描述
class Human{
talk(){
return 'talking';
}
}
class SuperHuman extends Human{
constructor(){
super();
this.age = 12;
}
fly(){
return 'flying';
}
}
let me = new Human();
let you = new SuperHuman();
you.gender = 'male';
console.log(you);
let she = Object.create(you);
console.log(she);
在学习原型继承时,she(object) proto 看起来像这样。
但我的期望是它应该看起来像这样......
为什么会这样显示?
解决方法
Devtools 只是告诉你 she
的原型是 a SuperHuman
(特别是 you
),而不是原型是函数 {{ 1}}。
SuperHuman
的原型链为:
she
-
she −> you −> SuperHuman.prototype −> Human.prototype −> Object.prototype
的原型是she
,因为您使用you
创建它。 -
Object.create(you)
的原型是you
,因为您使用SuperHuman.prototype
创建它。 -
new SuperHuman
的原型是SuperHuman.prototype
因为您通过Human.prototype
创建了SuperHuman
函数,该函数设置了两条继承链(一个用于class SuperHuman extends Human
对象另一个用于函数本身)。 -
prototype
的原型是Human.prototype
,因为Object.prototype
在没有class
时就是这样做的。
顺便说一句,不幸的是,某些 devtools 实现(例如基于 Chromium 的浏览器中的实现)使用 extends
,它们的意思是 [[Prototype]]
。一方面,它鼓励使用 __proto__
,但不应该使用它(并非所有对象都具有它,并且它可以被遮蔽;始终使用 __proto__
或 Object.getPrototypeOf
)。另外,它具有误导性:Chromium 的 devtools 会很高兴地向您显示 Object.setPrototypeOf
表示一个根本没有 __proto__
访问器属性的对象,因为它没有从 __proto__
继承(这是访问器来自):
Object.prototype
// An object with no prototype
const p = Object.create(null);
// An object using that as its prototype
const c = Object.create(p);
// An object inheriting from Object.prototype has the `__proto__` accessor property:
console.log("__proto__" in {}); // true
// `c` does not have the `__proto__` accessor property:
console.log("__proto__" in c); // false
// And yet,Chromium's devtools show you one if you expand it in the console
console.log(c);