MST

星途 面试题库

面试题:JavaScript 类继承与构造函数继承的实现及差异

请分别使用类继承和构造函数继承的方式实现一个简单的继承结构,父类有一个公共方法和属性,子类继承并扩展这些属性和方法。同时分析这两种继承方式在实现原理、语法以及使用场景上的差异。
27.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

类继承方式

// 定义父类
class Animal {
    constructor(name) {
        this.name = name;
    }
    speak() {
        console.log(`${this.name} makes a sound.`);
    }
}

// 定义子类
class Dog extends Animal {
    constructor(name, breed) {
        super(name);
        this.breed = breed;
    }
    bark() {
        console.log(`${this.name} barks.`);
    }
}

// 使用子类
let myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); 
myDog.bark(); 

构造函数继承方式

// 定义父构造函数
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function() {
    console.log(`${this.name} makes a sound.`);
};

// 定义子构造函数
function Dog(name, breed) {
    Animal.call(this, name);
    this.breed = breed;
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
Dog.prototype.bark = function() {
    console.log(`${this.name} barks.`);
};

// 使用子构造函数
let myDog = new Dog('Buddy', 'Golden Retriever');
myDog.speak(); 
myDog.bark(); 

差异分析

  1. 实现原理
    • 类继承:ES6 类继承基于原型链,通过 extends 关键字声明子类继承自父类,使用 super 调用父类构造函数,本质上还是原型继承的语法糖。
    • 构造函数继承:通过 callapply 方法在子类构造函数中调用父类构造函数,以借用父类的属性,然后通过 Object.create 来设置子类的原型为父类原型的实例,从而实现方法的继承。
  2. 语法
    • 类继承:语法简洁明了,使用 class 关键字定义类,extends 实现继承,super 调用父类构造函数和访问父类方法,更符合面向对象编程习惯。
    • 构造函数继承:使用函数定义构造函数,通过 call/apply 借用属性,通过原型赋值实现方法继承,语法相对复杂。
  3. 使用场景
    • 类继承:适用于现代 JavaScript 开发,尤其是在需要清晰表达继承关系和面向对象结构的场景,如大型应用开发、框架设计等。
    • 构造函数继承:在 ES6 之前广泛使用,对于一些需要兼容旧环境或者对性能优化有特定需求(如避免原型链上不必要的属性)的场景仍有一定价值。