为什么 __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.getPrototypeOf
或 Object.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.
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.getPrototypeOf
或 Object.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.