前端基础-ES基础2
6.3 ES6 与 ES5 继承的区别
参考答案:
ES6 中有类 class 的概念,类 class 的继承是通过 extends 来实现的,ES5 中是通过设置构造函数的 prototype 属性,来实现继承的。
ES6 与 ES5 中的继承有 2 个区别,第一个是,ES6 中子类会继承父类的属性,第二个区别是,super() 与 A.call(this) 是不同的,在继承原生构造函数的情况下,体现得很明显,ES6 中的子类实例可以继承原生构造函数实例的内部属性,而在 ES5 中做不到。
解析:
下面通过 3 个 demo,来分析它们之间的区别。
- ES5 继承
直接上代码:
function A() {
this.a = 'hello';
}
function B() {
A.call(this);
this.b = 'world';
}
B.prototype = Object.create(A.prototype, {
constructor: { value: B, writable: true, configurable: true }
});
let b = new B();
代码中,构造函数 B 继承构造函数 A,首先让构造函数 B 的 prototype 对象中的 proto 属性指向构造函数 A 的 prototype 对象,并且将构造函数 B 的 prototype 对象的 constructor 属性赋值为构造函数 B,让构造函数 B 的实例继承构造函数 A 的原型对象上的属性,然后在构造函数 B 内部的首行写上 A.call(this),让构造函数 B 的实例继承构造函数 A 的实例属性。在 ES5 中实现两个构造函数之间的继承,只需要做这两步即可。下面六幅图分别是,实例 b 的原型链及验证图,构造函数 B 的原型链及验证图,构造函数 A 的原型链及验证图。
实例 b 的原型链如下图:

实例 b 的原型链验证图:

构造函数 B 的原型链图下图:

构造函数 B 的原型链验证图图:

构造函数 A 的原型链图下图:

构造函数 B 的原型链验证图图:

从上面 6 幅图可知,构造函数 B 的实例 b 继承了构造函数 A 的实例属性,继承了构造函数 A 的原型对象上的属性,继承了构造函数 Object 的原型对象上的属性。构造函数 B 是构造函数 Function 的实例,继承了构造函数 Function 的原型对象上的属性,继承了构造函数 Object 的原型对象上的属性。 构造函数 A 是构造函数 Function 的实例,继承了构造函数 Function 的原型对象上的属性,继承了构造函数 Object 的原型对象上的属性。可看出,构造函数 A 与 构造函数 B 并没有继承关系,即构造函数 B 没有继承构造函数 A 上面的属性,在 ES6 中,用 extends 实现两个类的继承,两个类之间是有继承关系的,即子类继承了父类的方法,这是 ES6 与 ES5 继承的第一点区别,下面通过 ES6 的继承来说明这一点。
- ES6 继承
直接上代码:
class A {
constructor() {
this.a = 'hello';
}
}
class B extends A {
constructor() {
super();
this.b = 'world';
}
}
let b = new B();
复制代码
代码中,类 B 通过 extends 关键字继承类 A 的属性及其原型对象上的属性,通过在类 B 的 constructor 函数中执行 super() 函数,让类 B 的实例继承类 A 的实例属性,super() 的作用类似构造函数 B 中的 A.call(this),但它们是有区别的,这是 ES6 与 ES5 继承的第二点区别,这个区别会在文章的最后说明。在 ES6 中,两个类之间的继承就是通过 extends 和 super 两个关键字实现的。下面四幅图分别是,实例 b 的原型链及验证图,类 B 的原型链及验证图。
实例 b 的原型链如下图:

实例 b 的原型链验证图:

类 B 的原型链图下图:

类 B 的原型链验证图图:

通过上面 4 幅图可知,在 ES6 与 ES5 中,类 B 的实例 b 的原型链与构造函数 B 的实例 b 的原型链是相同的,但是在 ES6 中类 B 继承了类 A 的属性,在 ES5 中,构造函数 B 没有继承
剩余60%内容,订阅专栏后可继续查看/也可单篇购买
本面试宝典均来自校招面试题目大数据进行的整理

