MST
星途 面试题库

面试题:JavaScript中类与原型优化之方法复用

在JavaScript中,假设我们有一个构造函数`Animal`,它有`name`属性和`speak`方法。现在我们要创建`Dog`和`Cat`构造函数,它们继承自`Animal`,并且都有自己独特的`speak`方法。请用原型链的方式实现这一需求,并说明如何通过优化来避免重复定义方法。
32.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试
// 定义Animal构造函数
function Animal(name) {
    this.name = name;
}

// 定义Animal的speak方法
Animal.prototype.speak = function() {
    console.log(this.name +'makes a sound.');
};

// 定义Dog构造函数
function Dog(name) {
    // 借用Animal的构造函数初始化name属性
    Animal.call(this, name);
}

// 设置Dog的原型为Animal的实例,建立原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 重写Dog的speak方法
Dog.prototype.speak = function() {
    console.log(this.name +'barks.');
};

// 定义Cat构造函数
function Cat(name) {
    // 借用Animal的构造函数初始化name属性
    Animal.call(this, name);
}

// 设置Cat的原型为Animal的实例,建立原型链
Cat.prototype = Object.create(Animal.prototype);
Cat.prototype.constructor = Cat;

// 重写Cat的speak方法
Cat.prototype.speak = function() {
    console.log(this.name +'meows.');
};

// 优化避免重复定义方法
// 1. 公共方法定义在Animal.prototype上,子构造函数通过原型链继承,这样公共方法只会存在一份
// 2. 借用父构造函数初始化属性,避免在子构造函数中重复定义属性初始化逻辑

说明:

  1. 原型链继承实现
    • 通过Object.create方法创建一个以Animal.prototype为原型的新对象,并将其赋值给Dog.prototypeCat.prototype,从而建立原型链关系。
    • 使用Animal.call(this, name)在子构造函数中调用父构造函数,初始化name属性,这样每个实例都有自己独立的name属性。
    • Dog.prototypeCat.prototype分别重写speak方法,实现各自独特的行为。
  2. 优化避免重复定义方法
    • 将公共方法speak定义在Animal.prototype上,DogCat通过原型链继承该方法,而不是在每个子构造函数的实例上重复定义,减少内存开销。
    • 在子构造函数中通过Animal.call(this, name)借用父构造函数初始化name属性,避免在子构造函数中重复编写属性初始化代码。