Skip to content

原型链(Prototype Chain) 是 JavaScript 中实现继承的一种机制,它是基于对象的原型([[Prototype]])构成的一条“链条”,用于属性和方法的查找,

  • 每个对象都有一个隐藏的内部属性 [[Prototype]],可以通过 __proto__ 访问
  • 一个对象可以从其原型对象继承属性和方法,多个对象通过 [[Prototype]] 链接起来,形成一条原型链
  • 属性或方法查找会沿着这条链逐级向上查找,直到找到为止或到达 null(原型链的顶端)。 例如:
js
// alice --> Person.prototype --> Object.prototype --> null
function Person(name) {
  this.name = name;
}

Person.prototype.sayHello = function() {
  console.log("Hello, I’m " + this.name);
};

const alice = new Person("Alice");

alice.sayHello(); // => Hello, I’m Alice

其等价于 ES 6 的 class 语法糖:

js
class Person {
  constructor(name) {
    this.name = name;
  }

  sayHello() { // 加到Person的Person.prototype上,而非实例本身
    console.log(`Hello, I'm ${this.name}`);
  }
}

const alice = new Person('Alice');
alice.sayHello(); // Hello, I'm Alice

通过原型链也可以实现类的继承:

js
class Animal {
  speak() {
    console.log('Animal speaks');
  }
}

class Dog extends Animal {
  speak() {
    console.log('Dog barks');
  }
}

底层实现是:

  • Dog.prototype.__proto__ = Animal.prototype(子类原型继承父类原型)
  • Dog.__proto__ = Animal(子类构造函数继承父类构造函数)

【【前端八股文】原型和原型链】 https://www.bilibili.com/video/BV1LY411d7Yt/?share_source=copy_web&vd_source=320efa3d6a76c009ab23f7fcc174b3f4 其中 prototype 原型挂载到构造函数上,生成的实例可以使用这些原型方法。 每个对象都有一个 __proto__ 属性,指向其原型。 因此:

js
const arr = new Array(2,3,4);
console.log(arr.__proto__ === Array.prototype); // true

原型链就是原型的链式查找方式: image.png

总结

  1. 函数都有prototype属性
    • 称之为原型(prototype),也称为原型对象。
    • 原型可以放一些属性和方法,共享给实例对象使用。
    • 原型可以做继承。
  2. 对象都有__proto__属性
    • 这个属性指向它的原型对象。
    • 原型对象也是对象,也有__proto__属性,指向原型对象的原型对象。
    • 这样一层一层,就形成了一个链式结构,我们称之为原型链(prototype chain)。
    • 最顶层是 Object. prototype,它的__proto__指向 null,表示原型链的终点。

三种方法注册

注册位置写法调用方式用于
构造函数(静态方法)Person.method = fnPerson.method()工具方法、工厂
原型(实例方法)Person.prototype.method = fnp.method()方法共享
实例本身(每个对象)this.method = fn(构造内部)p.method()私有化、隔离