MST

星途 面试题库

面试题:JavaScript prototype 与 ES6 类继承的关系及差异

阐述 JavaScript 传统的基于 prototype 的继承方式和 ES6 引入的 class 关键字实现继承的内在联系与主要差异,包括但不限于语法、性能、原型链等方面。
29.7万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

内在联系

  1. 原型链基础:无论是传统基于 prototype 的继承还是 ES6 class 继承,本质上都依赖原型链来实现继承。在传统方式中,通过设置 prototype 属性来构建原型链;ES6 class 继承同样基于原型链,class 只是语法糖,其背后的实现依旧是原型链机制。例如:
// 传统方式
function Animal() {}
Animal.prototype.eat = function() {};
function Dog() {}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// ES6 class 方式
class Animal {
    eat() {}
}
class Dog extends Animal {}

在这两种方式下,Dog 实例的原型链最终都会指向 Animal 的原型。

主要差异

  1. 语法
    • 传统 prototype 方式:语法较为复杂和底层。需要手动创建构造函数,通过操作 prototype 属性来设置原型和构造函数,如上述 Dog 的继承实现。代码可读性相对较差,尤其是在处理多层继承时。
    • ES6 class 方式:语法更加简洁、清晰和直观,类似于其他面向对象语言(如 Java、C#)的类继承语法。使用 class 关键字定义类,extends 关键字实现继承,super 关键字调用父类的构造函数和方法。例如:
class Parent {
    constructor(x) {
        this.x = x;
    }
    printX() {
        console.log(this.x);
    }
}
class Child extends Parent {
    constructor(x, y) {
        super(x);
        this.y = y;
    }
    printY() {
        console.log(this.y);
    }
}
  1. 性能
    • 传统 prototype 方式:在创建对象和构建原型链时,性能相对较低,因为涉及较多手动操作和中间步骤。例如创建中间的 Object.create 操作,可能会带来一些额外的性能开销。
    • ES6 class 方式:由于是语法糖,在性能上与传统 prototype 方式基本相同。不过,现代 JavaScript 引擎针对 class 语法进行了优化,在某些情况下可能会有更好的性能表现。但总体而言,两者性能差异不大,性能瓶颈通常在其他方面(如复杂计算、DOM 操作等)。
  2. 原型链操作
    • 传统 prototype 方式:开发者需要直接操作原型对象,如修改 prototype 属性,手动设置构造函数等,这容易出错。例如,错误地修改原型对象可能会导致原型链混乱,影响继承关系。
    • ES6 class 方式:对原型链操作进行了封装,开发者不需要直接操作原型对象。通过 super 关键字来调用父类的构造函数和方法,使得原型链的管理更加安全和便捷。例如在子类构造函数中,必须先调用 super() 才能使用 this,这保证了原型链的正确初始化。