MST

星途 面试题库

面试题:JavaScript 中类和原型性能优化之原型链理解

请阐述 JavaScript 中原型链的概念,以及它在类和原型性能优化方面起到了什么作用。举例说明如何通过合理利用原型链来避免重复定义方法从而提升性能。
43.2万 热度难度
编程语言JavaScript

知识考点

AI 面试

面试题答案

一键面试

原型链概念

在 JavaScript 中,每个对象都有一个 [[Prototype]] 内部属性(在现代 JavaScript 中可以通过 __proto__ 访问,虽然 __proto__ 已不推荐直接使用,但为了便于理解可以这么看),这个属性指向该对象的原型对象。原型对象本身也是一个对象,它也有自己的 [[Prototype]],以此类推形成一条链式结构,直到原型链的末端(通常是 null),这条链式结构就被称为原型链。

当访问一个对象的属性或方法时,如果该对象自身没有定义这个属性或方法,JavaScript 引擎就会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的末端(null)。如果到达 null 仍未找到,则返回 undefined

原型链在类和原型性能优化方面的作用

  1. 避免重复定义:通过原型链,多个对象实例可以共享原型对象上的属性和方法,而不必在每个实例上重复创建,从而节省内存空间,提升性能。例如,在模拟类的继承场景中,子类实例可以通过原型链访问到父类原型上定义的方法,而无需在子类每个实例中都重新定义这些方法。
  2. 代码复用:有利于代码复用,减少冗余代码。将通用的属性和方法定义在原型上,所有基于该原型创建的对象都能受益,提高开发效率。

举例说明如何合理利用原型链提升性能

// 定义一个构造函数
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 的原型为 Animal 的实例,建立原型链
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 在 Dog 原型上定义特有的方法
Dog.prototype.bark = function() {
    console.log(this.name +'barks.');
};

// 创建两个 Dog 实例
let dog1 = new Dog('Buddy', 'Golden Retriever');
let dog2 = new Dog('Max', 'Labrador');

// 两个实例共享 Animal 原型上的 speak 方法,而不是各自拥有一份
dog1.speak(); // Buddy makes a sound.
dog2.speak(); // Max makes a sound.

在上述例子中,Animal 构造函数的 speak 方法定义在原型上,Dog 构造函数通过原型链继承了 Animal 原型上的 speak 方法。dog1dog2 这两个 Dog 实例无需重复定义 speak 方法,而是通过原型链共享该方法,节省了内存,提升了性能。