在 JavaScript 中,原型(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');
const bob = new Person('Bob');

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

在上述示例中,greet 方法被添加到 Person 的原型对象上,因此 alicebob 实例都可以调用该方法。

原型链

JavaScript 对象通过原型链实现继承。当访问一个对象的属性或方法时,JavaScript 引擎会首先查找该对象自身的属性或方法;如果未找到,则会沿着原型链向上查找,直到找到相应的属性或方法,或到达原型链的顶端(即 null)。

const animal = {
  eats: true
};

const rabbit = Object.create(animal);
rabbit.jumps = true;

console.log(rabbit.eats);   // 输出: true
console.log(rabbit.jumps);  // 输出: true

在此示例中,rabbit 对象的原型是 animal 对象。当访问 rabbit.eats 时,由于 rabbit 自身没有 eats 属性,JavaScript 会在其原型 animal 上查找该属性。

__proto__Object.getPrototypeOf

每个对象都有一个内部属性 [[Prototype]],通常可以通过 __proto__ 来访问。然而,__proto__ 并不是标准属性,建议使用 Object.getPrototypeOf 方法来获取对象的原型。

const obj = {};
console.log(Object.getPrototypeOf(obj) === Object.prototype); // 输出: true

通过理解和使用原型机制,开发者可以更有效地实现对象之间的属性和方法共享,从而编写出更高效、简洁的代码。