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);
when study prototypal inheritance the she(object) proto looks like this.
but my expectation is it should look like this...
Why it shows in this way?
Devtools is just telling you that the prototype of she
is a SuperHuman
(specifically, you
), not that the prototype is the function SuperHuman
.
The prototype chain of she
is:
she −> you −> SuperHuman.prototype −> Human.prototype −> Object.prototype
she
's prototype is you
because you created it with Object.create(you)
.you
's prototype is SuperHuman.prototype
because you created it with new SuperHuman
.SuperHuman.prototype
's prototype is Human.prototype
because you created the SuperHuman
function via class SuperHuman extends Human
which sets up two chains of inheritance (one for the prototype
objects and the other for the functions themselves).Human.prototype
's prototype is Object.prototype
because that's what class
does when there's no extends
.As a complete aside, it's unfortunate that some devtools implementations (such as the one in Chromium-based browsers) use __proto__
where what they mean is [[Prototype]]
. For one thing, it encourages using __proto__
, which one shouldn't (not all objects have it and it can be shadowed; always use Object.getPrototypeOf
or Object.setPrototypeOf
). Separately, it's misleading: Chromium's devtools will happily show you __proto__
for an object that doesn't have the __proto__
accessor property at all because it doesn't inherit from Object.prototype
(which is where the accessor comes from):
// 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.