前端面试原型链高频

原型链简介

在 JavaScript 中,每个对象都可以通过原型链(Prototype Chain)继承属性和方法。可以把原型链想象成一个对象的层级结构,通过这个结构,属性和方法可以被层层传递下来。

核心概念

  1. 原型(Prototype)
    • 原型是一个对象,每个对象都连接到另一个对象,我们称之为它的“原型”。如果一个对象自身没有某个属性或方法,JavaScript 就会在它的原型上找,这就是原型链的基础。
  2. 原型链
    • 这是一种对象之间的连接方式,通过这个连接,一个对象可以“继承”另一个对象的属性和方法。如果没有找到属性或方法,查找会沿着原型链一直向上,直到 null
  3. 构造函数和 prototype 属性
    • 在 JavaScript 中,函数也可以作为构造函数使用,用来创建对象。每个函数都有一个 prototype 属性,它指向一个对象,所有该函数创建的实例都会共享这个对象的属性和方法。

示例

function Person(name) {
  this.name = name;
}

Person.prototype.greet = function() {
  console.log(`Hello, my name is ${this.name}`);
};

let john = new Person('John');
john.greet(); // 输出: Hello, my name is John

在这个例子中,Person 是一个构造函数。通过 Person 创建的 john 对象可以访问 Person.prototype 上的 greet方法,因为 john 的原型链上包含 Person.prototype


🔍 原型链的底层原理

__proto__ 和 prototype

  1. __proto__
    • __proto__ 是一个指向对象原型的隐藏属性,可以用来访问或设置对象的原型。虽然不推荐在现代代码中使用,但它在理解原型链时非常有用。
  2. prototype
    • prototype 是构造函数的属性,用于定义共享的属性和方法。所有通过这个构造函数创建的对象实例都会共享 prototype 中定义的内容。

原型链查找机制

  • 当访问对象的某个属性时,JavaScript 会首先在对象自身查找,如果没有找到,就会沿着原型链向上查找,直到找到属性或到达原型链的顶端(即原型为 null)。

性能考虑

  • 原型链较短时查找性能较好,但链过长可能会降低查找性能。因此,设计时应保持原型链简单。

🎓 重要案例

继承与方法重写

function Animal(name) {
  this.name = name;
}

Animal.prototype.speak = function() {
  console.log(`${this.name} makes a noise.`);
};

function Dog(name) {
  Animal.call(this, name);
}

Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

Dog.prototype.speak = function() {
  console.log(`${this.name} barks.`);
};

let dog = new Dog('Rex');
dog.speak(); // 输出: Rex barks.

  • 解释: 这里展示了如何使用原型链实现继承和方法重写。Dog 继承了 Animal 的属性和方法,并重写了 speak方法。Dog.prototype = Object.create(Animal.prototype) 这行代码设置了 Dog 的原型链,使其继承自 Animal

使用 Object.setPrototypeOf 和 Object.getPrototypeOf

let animal = {
  speak() {
    console.log("Animal speaks");
  }
};

let dog = {
  bark() {
    console.log("Dog barks");
  }
};

Object.setPrototypeOf(dog, animal);
dog.speak(); // 输出: Animal speaks
console.log(Object.getPrototypeOf(dog)); // 输出: animal 对象

  • 解释: 使用 Object.setPrototypeOf 可以动态设置对象的原型,这在需要更改原型链的结构时非常有用。而 Object.getPrototypeOf 则可以获取对象的原型。

💡 总结与最佳实践

  • 合理使用原型链: 原型链可以实现属性和方法的共享,但应避免过度使用深层次的继承。
  • 性能优化: 设计时应保持原型链简单,避免过长的继承链导致性能问题。
  • 现代开发注意事项: 现代 JavaScript 开发中,更推荐使用 Object.getPrototypeOf 和 Object.setPrototypeOf来操作原型,而不是使用过时的 __proto__
  • 5
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值