还不懂原型与原型链?快过来看看吧!

156 阅读2分钟

一文带你搞懂原型(prototype)和原型链(prototype chain)

原型(prototype)和原型链(prototype chain)是 JavaScript 中两个重要的概念,理解它们有助于掌握 JavaScript 的继承机制和对象的属性查找机制。

image.png

原型 (Prototype)

JavaScript 中,每个对象都有一个隐藏的内置属性 [[Prototype]],它要么是另一个对象,要么是 null。我们通常通过 __proto__ 属性访问这个属性(虽然不推荐直接使用这个属性)。这个 [[Prototype]] 指向的对象称为该对象的原型。

当你创建一个对象时,可以通过对象的构造函数的 prototype 属性来指定这个对象的原型。

例如:

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

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

const alice = new Person("Alice");
alice.greet(); // 输出: Hello, my name is Alice

在这个例子中,Person 是一个构造函数,Person.prototype 是一个对象,包含了一个方法 greet。当我们用 new Person('Alice') 创建一个新对象时,这个新对象的 [[Prototype]] 属性会被设置为 Person.prototype

原型链 (Prototype Chain)

当访问一个对象的属性时,JavaScript 引擎会首先检查这个对象本身是否有这个属性。如果没有,它会沿着 [[Prototype]] 链向上查找,直到找到该属性或到达原型链的末尾(即 null)。

这个由对象及其原型构成的链条就称为原型链。

例如:


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

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

const alice = new Person('Alice');
console.log(alice.hasOwnProperty('name')); // 输出: true
console.log(alice.hasOwnProperty('greet')); // 输出: false
console.log(alice.**proto**.hasOwnProperty('greet')); // 输出: true

alice.greet(); // 输出: Hello, my name is Alice

在上面的例子中,当我们调用 alice.greet() 时,JavaScript 引擎会在 alice 对象中查找 greet 方法。因为 alice 本身没有 greet 方法,JavaScript 引擎会沿着原型链向上查找,最终在 Person.prototype 中找到了 greet 方法并调用它。

原型链的延伸

原型链可以是多层的。例如:

function Animal() {}
Animal.prototype.walk = function () {
  console.log("Walking...");
};

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

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

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

const bob = new Person("Bob");
bob.walk(); // 输出: Walking...
bob.greet(); // 输出: Hello, my name is Bob

在这个例子中,Person.prototype 设置为 Animal.prototype 的一个新对象。因此,bob 对象的原型链是:

  1. bob 本身
  2. Person.prototype
  3. Animal.prototype
  4. Object.prototype
  5. null 当我们调用 bob.walk() 时,JavaScript 引擎会沿着原型链查找 walk 方法,最终在 Animal.prototype 中找到。

总结

  • 原型:每个对象都有一个内部属性 [[Prototype]],指向它的原型。
  • 原型链:当访问一个对象的属性时,JavaScript 引擎会沿着对象的 [[Prototype]] 链向上查找,直到找到该属性或到达链的末尾。
  • 理解原型和原型链是掌握 JavaScript 面向对象编程的重要基础。通过这两个概念,JavaScript 实现了继承和属性共享机制。