原型链是 JavaScript 中用于实现对象继承的机制。每个对象都有一个原型(prototype),而原型又是一个对象。当我们访问一个对象的属性或方法时,如果该对象自身没有定义该属性或方法,JavaScript 就会从它的原型中查找,如果原型中也不存在,则会再向上查找,直到找到该属性或方法或者达到原型链的顶端。
JavaScript 中的原型链是通过对象的 proto 属性来实现的。每个对象都有一个 proto 属性,它指向该对象的原型。通过原型链,可以让一个对象继承另一个对象的属性和方法。
当我们访问一个对象的属性或方法时,JavaScript 首先会在该对象自身查找,如果找不到,则会通过该对象的 proto 属性指向的原型去查找,如果还找不到,则再通过该原型的 proto 属性指向的原型去查找,一直循环向上查找,直到找到该属性或方法,或者到达原型链的顶端(即 Object.prototype)。
通过原型链,可以实现对象之间的继承关系。当一个对象作为另一个对象的原型时,后者可以继承前者的属性和方法。这种继承关系是基于原型链的,而不是基于类或构造函数。
例如,如果我们创建一个对象 person,并设置其原型为一个对象 animal,那么 person 就可以继承 animal 的属性和方法。如果找不到属性或方法,JavaScript 就会沿着原型链向上查找,直到找到或者到达原型链的顶端。
原型链是 JavaScript 中实现对象继承的重要概念,它为我们提供了一种灵活的继承机制,可以更好地组织和复用代码。同时,理解原型链也有助于我们更好地理解 JavaScript 中的对象和原型的相关概念。

当我们使用构造函数和原型链来创建对象时,就可以清晰地看到原型链的实际应用。

// 创建一个动物对象的构造函数
function Animal(name) {
  this.name = name;
}

// 向动物对象的原型中添加一个方法
Animal.prototype.sayHello = function() {
  console.log("Hello, I'm a " + this.name);
};

// 创建一个狗对象的构造函数,将狗的原型设置为动物对象的实例
function Dog(name, breed) {
  Animal.call(this, name);
  this.breed = breed;
}

// 设置狗的原型为动物对象的实例
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;

// 向狗对象的原型中添加一个方法
Dog.prototype.bark = function() {
  console.log("Woof!");
};

// 创建一个狗实例
var myDog = new Dog("Max", "Labrador");

// 调用狗实例的方法
myDog.sayHello();  // 输出:Hello, I'm a Max
myDog.bark();      // 输出:Woof!

在上面的例子中,我们首先定义了一个构造函数 Animal,然后将其原型上添加了 sayHello 方法。接下来,我们定义了构造函数 Dog,并使用 Object.create() 方法将 Dog 的原型设置为 Animal 的一个实例。这样,Dog 对象就可以继承 Animal 的属性和方法。我们还在 Dog 的原型上添加了一个新的方法 bark。

最后,我们通过实例化 Dog 构造函数,创建了一个名为 myDog 的狗实例,并可以调用继承自 Animal 的 sayHello 方法和 Dog 的 bark 方法。这就展示了原型链的继承关系,在对象间实现了属性和方法的共享与继承。