MST

星途 面试题库

面试题:JavaScript 类继承与原型链的复杂应用

假设有一个复杂的 JavaScript 类继承体系,基类 `Animal` 有属性和方法,`Dog` 类继承自 `Animal` 并添加了新的属性和方法,`Poodle` 类又继承自 `Dog` 且重写了部分方法。请编写代码实现这个继承体系,并阐述当调用 `Poodle` 实例的某个方法时,JavaScript 引擎是如何沿着原型链查找该方法的,同时说明可能遇到的性能问题及优化方法。
24.5万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

代码实现

// 基类 Animal
function Animal(name) {
    this.name = name;
}
Animal.prototype.speak = function() {
    console.log(this.name +'makes a sound.');
};

// Dog 类继承自 Animal
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.');
};

// Poodle 类继承自 Dog
function Poodle(name, breed, color) {
    Dog.call(this, name, breed);
    this.color = color;
}
Poodle.prototype = Object.create(Dog.prototype);
Poodle.prototype.constructor = Poodle;
Poodle.prototype.bark = function() {
    console.log(this.name +'barks softly.');
};

原型链查找方法过程

当调用 Poodle 实例的某个方法时,JavaScript 引擎首先在 Poodle 实例本身查找该方法,如果没找到,就会沿着原型链向上查找。具体来说,先查找 Poodle.prototype,如果没找到,再查找 Dog.prototype,接着查找 Animal.prototype,如果一直到 Object.prototype 都没找到,就返回 undefined

性能问题

  1. 查找开销:原型链较长时,查找方法需要遍历原型链,增加查找时间。
  2. 内存占用:每个实例都有一个指向原型的指针,当有大量实例时,会占用较多内存。

优化方法

  1. 减少原型链深度:尽量避免过深的继承层次,减少查找路径。
  2. 使用对象组合替代继承:通过将对象的功能组合在一起,而不是通过继承,减少原型链的依赖。
  3. 缓存方法:如果某个方法经常被调用,可以在实例化时将其缓存到实例上,避免每次都从原型链查找。