MST

星途 面试题库

面试题:JavaScript 为已有类添加方法的作用域与性能考量

已知有一个全局定义的 `Animal` 类,有属性 `species`。现在要为 `Animal` 类添加一个 `makeSound` 方法,该方法在不同的实例下输出不同的声音(比如 'Dog' 实例输出 '汪汪','Cat' 实例输出 '喵喵')。请从作用域和性能的角度分析,使用原型链添加方法和使用类语法直接添加方法这两种方式各有什么优缺点,并分别实现这两种方式添加 `makeSound` 方法。
25.0万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

使用原型链添加方法

优点

  • 节省内存:所有实例共享原型上的方法,不会在每个实例中重复创建相同的方法,从性能角度有利于节省内存,尤其是在创建大量实例时。
  • 作用域清晰:原型链的查找机制使得方法的作用域基于原型对象,当访问实例的方法时,会沿着原型链查找,这种机制在理解和维护继承关系时较为清晰。

缺点

  • 原型污染风险:如果不小心在原型对象上直接修改了属性或方法,可能会影响到所有基于该原型的实例,存在原型污染的潜在风险。

实现代码

function Animal(species) {
    this.species = species;
}
Animal.prototype.makeSound = function() {
    if (this.species === 'Dog') {
        return '汪汪';
    } else if (this.species === 'Cat') {
        return '喵喵';
    }
    return '';
};

使用类语法直接添加方法

优点

  • 语法简洁直观:ES6 类语法更符合面向对象编程的习惯,代码结构清晰,易于理解和编写,尤其对于熟悉传统面向对象语言的开发者。
  • 减少原型污染风险:相比于直接操作原型,类语法在一定程度上封装了内部实现,降低了意外修改原型导致污染的风险。

缺点

  • 内存占用:如果从严格的内存占用角度看,每个实例都有自己独立的方法副本(虽然现代 JavaScript 引擎可能对此有优化),相比原型链共享方法,可能会占用更多内存,特别是在实例数量庞大时。

实现代码

class Animal {
    constructor(species) {
        this.species = species;
    }
    makeSound() {
        if (this.species === 'Dog') {
            return '汪汪';
        } else if (this.species === 'Cat') {
            return '喵喵';
        }
        return '';
    }
}