>[danger]介绍一下Js中的原型链 在 JavaScript 中,所有的对象都有一个隐藏属性 `[[Prototype]]`(可以通过 `Object.getPrototypeOf(obj)` 或 `__proto__` 来访问),用于指向其原型对象。原型对象也是一个对象,拥有自己的 `[[Prototype]]`,形成了一个原型链。 当我们访问一个对象的属性时,如果该对象本身没有这个属性,JavaScript 引擎会沿着原型链向上查找,直到找到该属性或者到达原型链的末端(即 `null`)。这样就可以实现属性的继承。 下面是一个简单的示例来说明原型链的工作原理: ```javascript // 定义一个 "父类" 构造函数 function Animal(name) { this.name = name; } // 在父类的原型对象上定义方法 Animal.prototype.eat = function() { console.log(`${this.name} is eating.`); }; // 定义一个 "子类" 构造函数 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! My name is ${this.name}. I am a ${this.breed}.`); }; const dog = new Dog('Bobby', 'Golden Retriever'); dog.eat(); // 继承自父类 Animal 的方法 dog.bark(); // 子类 Dog 自己的方法 ``` 在上述示例中,我们定义了一个简单的父类 `Animal` 和一个子类 `Dog`。通过 `Object.create()` 方法,将子类的原型对象指向父类的原型对象,建立了原型链的关系。 当我们访问 `dog.eat()` 方法时,JavaScript 引擎首先在 `dog` 实例上查找是否有 `eat` 属性,没有找到,然后沿着原型链向上查找,在父类 `Animal.prototype` 上找到了该方法,并调用之。 同样地,当我们访问 `dog.bark()` 方法时,JavaScript 引擎在 `dog` 实例上查找是否有 `bark` 属性,没有找到,然后沿着原型链向上查找,在子类 `Dog.prototype` 上找到了该方法,并调用之。 这样,通过原型链,子类可以继承父类的属性和方法,并且还可以在自己的原型对象上定义自己的方法。这种原型链的继承方式是 JavaScript 中实现面向对象编程的基础。