为什么 __proto__ 引用名称对于继承的对象来说看起来是错误的?

Why __proto__ reference name look like wrong for inherited object?

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);

在研究原型继承时,她(对象)proto 看起来像这样。

但我的期望是它应该看起来像这样...

为什么会这样显示?

Devtools 只是告诉你 she 的原型是 a SuperHuman(具体来说,you),而不是那个原型是函数 SuperHuman.

she的原型链为:

she −> you −> SuperHuman.prototype −> Human.prototype −> Object.prototype
  • she 的原型是 you 因为你用 Object.create(you).
  • 创建了它
  • you 的原型是 SuperHuman.prototype 因为你用 new SuperHuman.
  • 创建了它
  • SuperHuman.prototype 的原型是 Human.prototype 因为你通过 class SuperHuman extends Human 创建了 SuperHuman 函数,它设置了两个继承链(一个用于 prototype 对象,另一个用于函数本身)。
  • Human.prototype 的原型是 Object.prototype 因为当没有 extends.
  • class 就是这样做的

顺便说一句,不幸的是,某些开发工具实现(例如基于 Chromium 的浏览器中的实现)使用 __proto__,而它们的意思是 [[Prototype]]。一方面,它鼓励使用 __proto__,这是不应该的(不是所有对象都有它,它可以被隐藏;总是使用 Object.getPrototypeOfObject.setPrototypeOf)。另外,它具有误导性:Chromium 的开发工具会很乐意向您显示 __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);
Look in the real browser console.