理解 js 中的原型和原型链

2024-06-28 13:51:48 87
在 JavaScript 中,原型(prototype)和原型链(prototype chain)是理解对象继承和属性查找机制的核心概念。以下是详细解释:

原型(prototype)

每个 JavaScript 对象(除了 null)在创建时都有一个与之关联的对象,这个对象称为原型(prototype)。每个函数都有一个 prototype 属性,该属性是一个对象,用于为构造函数创建的实例提供共享的属性和方法。

示例

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

Person.prototype.greet = function() {
    console.log('Hello, ' + this.name);
};

const alice = new Person('Alice');
alice.greet();  // 输出: Hello, Alice

在这个示例中,Person 构造函数的 prototype 属性被设置了一个 greet 方法,所有由 Person 构造函数创建的实例都可以访问这个方法。

原型链(prototype chain)

当访问对象的属性或方法时,JavaScript 引擎首先在对象自身的属性中查找。如果找不到,则会沿着原型链向上查找,直到找到该属性或方法,或者到达原型链的顶端(即 Object.prototype),如果仍然找不到,则返回 undefined

示例

const obj = {
    a: 1
};

const obj2 = Object.create(obj);
obj2.b = 2;

const obj3 = Object.create(obj2);
obj3.c = 3;

console.log(obj3.a);  // 输出: 1
console.log(obj3.b);  // 输出: 2
console.log(obj3.c);  // 输出: 3

在这个示例中,obj3 通过原型链依次查找属性 abc

深入理解

  1. 构造函数和原型

    • 每个构造函数都有一个 prototype 属性,它指向一个对象,该对象包含由该构造函数创建的实例共享的属性和方法。
    • 示例中,Person.prototype.greet 是所有 Person 实例共享的方法。
  2. 原型对象

    • 原型对象本身也有一个 constructor 属性,指回关联的构造函数。
    • 示例中,Person.prototype.constructor 指向 Person 构造函数。
  3. 原型链机制

    • 当访问对象属性时,首先在对象自身查找,如果找不到,则沿着原型链查找。
    • 示例中,obj3 没有 a 属性,因此沿原型链查找 obj2obj 直到找到 a 属性。
  4. Object.prototype

    • 所有对象最终都会继承自 Object.prototype,这是原型链的顶端。
    • Object.prototype 上定义了一些通用的方法,如 toStringhasOwnProperty 等。

结论

理解 JavaScript 中的原型和原型链对掌握对象继承和属性查找机制至关重要。通过构造函数、原型对象和原型链的概念,可以更有效地组织和复用代码。