ES5/ES6 继承的除了写法之外的根本区别??

815 阅读3分钟

前言

突然最近在网上看到了这个面试题,看到好多人总结了class关键字的一些特性。我个人觉得是有一些关系的,不过我更趋向于另一部分的解释,是有些偏题。零零散散今天总结一下。


JavaScript相比于其他面向类的语言,在实现继承时并没有真正对构造类进行复制,当我们使用var children = new Parent()继承父类时,我们理所当然的理解为children ”为parent所构造“。实际上这是一种错误的理解。严格来说,JS才是真正的面向对象语言,而不是面向类语言。它所实现的继承,都是通过每个对象创建之初就存在的prototype属性进行关联、委托,从而建立练习,间接的实现继承,实际上不会复制父类。

ES5最常见的两种继承:原型链继承、构造函数继承

整个继承过程,都是通过原型链之间的指向进行委托关联,直到最后形成了”由构造函数所构造“的结局。

第二种,构造函数继承

构造继承关键在于,通过在子类的内部调用父类,即通过使用apply()或call()方法可以在将来新创建的对象上获取父类的成员和方法

ES6继承

ES6中新增了class关键字来定义类,通过保留的关键字extends实现了继承。实际上这些关键字只是一些语法糖,底层实现还是通过原型链之间的委托关联关系实现继承。

再来看两个案例

ES5继承(原型链继承)

ES6继承(extends继承)

对比代码可以知道,子类的继承都是成功的,但是问题出在,子类的_proto_ 指向不一样。

总结

  • 区别于ES5的继承,ES6的继承实现在于使用super关键字调用父类,反观ES5是通过call或者apply回调方法调用父类。

  • ES5 的子类和父类一样,都是先创建好,再实现继承的,所以它们的指向都是 [Function] 。

  • ES6 则得到不一样的结果,它指向父类,那么我们应该能推算出来,它的子类是通过 super 来改造的。

根据 es6--阮一峰 在class继承里面的说法,是这样子的:

引用阮一峰的 ECMAScript6入门 的class继承篇: 子类必须在constructor方法中调用super方法,否则新建实例时会报错。这是因为子类自己的this对象,必须先通过父类的构造函数完成塑造,得到与父类同样的实例属性和方法,然后再对其进行加工,加上子类自己的实例属性和方法。如果不调用super方法,子类就得不到this对象。 ES5 的继承,实质是先创造子类的实例对象this,然后再将父类的方法添加到this上面(Parent.apply(this))。ES6 的继承机制完全不同,实质是先将父类实例对象的属性和方法,加到this上面(所以必须先调用super方法),然后再用子类的构造函数修改this。

欢迎添加指导,叮~