简述ES5/ES6 的继承除了写法以外还有什么区别 ?
ES5和ES6提供的继承机制在表面上主要的区别是语法上的,但深入来看,它们在行为和内部机制上也存在一些差异。以下是ES5基于原型链和ES6基于class
语法继承机制除了写法之外的主要区别:
1. 构造函数和原型链 vs. class和extends
- ES5:继承是通过构造函数和原型链实现的。子类构造函数内部通过调用父类构造函数(
Parent.call(this)
)实现属性继承,通过将子类的原型设置为父类的实例(Child.prototype = new Parent()
)实现方法继承。 - ES6:继承通过
class
和extends
关键字以声明方式实现。ES6的类语法让继承看起来更像是传统面向对象编程语言中的类继承。
2. Super 关键字
- ES5:没有内置的
super
机制,必须手动调用父类构造函数和方法。 - ES6:引入了
super
关键字,用于调用父类的构造函数和方法,使得访问和调用父类成员变得简单直观。
3. 静态方法继承
- ES5:静态方法和属性需要手动复制到子类。
- ES6:静态方法和属性会自动被子类继承。
4. 类定义的严格模式
- ES5:类(构造函数和原型方法)的严格模式取决于函数体内是否声明使用严格模式(
"use strict"
)。 - ES6:所有通过
class
关键字定义的类都运行在严格模式下,无需显式声明,提高了代码的安全性和可维护性。
5. 新建实例的机制
- ES5:可以不通过
new
关键字调用构造函数,虽然这通常会导致错误或意外的行为。 - ES6:使用
class
定义的类不能不使用new
来调用,尝试这么做会抛出错误,这增加了类的使用安全性。
6. 对象原型和构造函数的链接
- ES5:需要手动设置子类的
prototype.constructor
属性指向自身,保证实例化对象的正确性。 - ES6:使用
class
和extends
时,这一链接自动正确设置,无需手动干预。
7. 类声明的提升(Hoisting)
- ES5:函数声明会被提升,但函数表达式(包括通过函数表达式定义的类)不会。
- ES6:类声明不会被提升,使用类之前必须先声明,这有助于避免运行时错误。
这些区别显示,ES6的class
和extends
提供了一种更为现代和易于理解的方式来实现类和继承,同时也改进了一些ES5继承机制中的局限和不便之处。