使用__proto__
来解释继承原理可以帮助理解 JavaScript 的原型链机制
基本概念
__proto__
:是一个非标准的属性,指向对象的原型。实际上,__proto__
是对象内部的[[Prototype]]
属性的非标准访问方式。在现代 JavaScript 中,可以使用 Object.getPrototypeOf()
和 Object.setPrototypeOf()
代替。
继承原理的解释
-
构造函数与原型设置:
- 创建一个构造函数,例如
Animal
。 - 通过设置构造函数的
prototype
属性来定义实例共享的方法。 - 新创建的对象的
__proto__
指向构造函数的prototype
。
function Animal(name) {
this.name = name;
}
Animal.prototype.say = function() {
console.log('I am an animal');
};
在这个例子中:
-
Animal.prototype
是Animal
构造函数的原型对象。 -
Animal.prototype.__proto__
指向Object.prototype
(原型链的顶端)。
-
创建继承关系:
- 创建另一个构造函数
Mammal
,并设置Mammal.prototype
的原型为Animal.prototype
。
function Mammal(name, furColor) {
Animal.call(this, name); // 继承 Animal 的属性
this.furColor = furColor;
}
Mammal.prototype = Object.create(Animal.prototype);
Mammal.prototype.constructor = Mammal;
在这个例子中:
-
Mammal.prototype
的__proto__
被设置为Animal.prototype
。也就是说,Mammal.prototype.__proto__
指向Animal.prototype
。
-
实例的原型链:
- 创建
Mammal
实例时,实例的__proto__
指向Mammal.prototype
,而Mammal.prototype.__proto__
指向Animal.prototype
。
const mammal = new Mammal('Lion', 'golden');
在这个例子中:
-
mammal.__proto__
是Mammal.prototype
。 -
mammal.__proto__.__proto__
(即Mammal.prototype.__proto__
)是Animal.prototype
。
-
访问属性和方法:
- 当访问
mammal
的属性或方法时,JavaScript 引擎会首先检查mammal
本身。 - 如果在
mammal
中找不到,JavaScript 引擎会沿着原型链查找,即检查mammal.__proto__
和mammal.__proto__.__proto__
,直到找到或到达原型链的顶端(Object.prototype
)。
console.log(mammal.name); // 输出: Lion (直接从实例对象中找到)
console.log(mammal.furColor); // 输出: golden (直接从实例对象中找到)
console.log(mammal.say()); // 输出: I am an animal (从 Animal.prototype 找到)
在这个例子中:
-
mammal
直接拥有name
和furColor
属性。 -
say
方法是从Mammal.prototype.__proto__
(即Animal.prototype
)中继承的。
总结
子类的 prototype 的 __proto__ 指向父类的 prototype,形成一个原型链。
实例对象的 __proto__ 指向实例的构造函数的 prototype,从而允许访问继承的属性和方法。
这个机制使得 JavaScript 实现了对象的继承和方法的共享。希望这个解释有帮助!