关于js的继承的问题?

class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true

看阮一峰的写的es6的class继承,下面有一句话:

这两条继承链,可以这样理解:作为一个对象,子类(B)的原型(__proto__属性)是父类(A);作为一个构造函数,子类(B)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

后半句话是不是错了:

作为一个构造函数,子类(B)的原型对象(prototype属性)是父类的原型对象(prototype属性)的实例。

是不是应该改为:
作为一个构造函数,子类(B)的原型对象(prototype属性)是父类的实例

阅读 1.6k
2 个回答

原文没错。但原文表达得不好。

ES标准中并没有prototype是父类prototype实例的说法。本质上,是基于父类superclassprototype创建了一个新的对象,并且把superclassprototype放到了新创建的对象的内置[[prototype]]插槽中(详见Runtime Semantics: ClassDefinitionEvaluationOrdinaryObjectCreate)。

并且,由于在访问一个对象时,如果对象上不存在这个属性,但在[[prototype]]内部插槽的对象上存在这个属性时,对象继承了访问权限(没有所属权),让这个属性表现为这个对象原型上的属性(详见Ordinary Object Internal Methods and Internal Slots)。

通常情况下,如果一个对象B的原型是另一个对象A,人们将它简单地理解为B继承自A,或称A为B的构造类。对于对象B是一个类的情况,将A称为B的父类。所以原文在“理解”上并没有错。我想你对于通过B.__proto__ === A得出A是B的父类肯定不会有疑问,那么现在将B替换为B.prototypeA替换为A.prototype,即(B.prototype).__proto__ === (A.prototype),同理可得A.prototypeB.prototype的父类。

不过,原文的“理解”是从实际看到的出发得出的结论,也就是通过原型的指向得出的父类关系。而实际上,除了构造器本身具备父子关系之外,原型对象只不过通过创建新对象建立了指向关系。这与类是完全独立的过程,所以不存在父子关系。因此,从运行结果的表象上去推论并不是一个特别准确的描述。

撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
推荐问题