原型链的构建
- 在JavaScript中,每个函数都有一个
prototype
属性,这个属性是一个对象,它默认有一个constructor
属性,指向该函数本身。例如:
function Person() {}
console.log(Person.prototype.constructor === Person); // true
- 当使用
new
关键字调用构造函数创建实例时,该实例的内部会有一个指向构造函数prototype
属性的链接(在现代JavaScript引擎中,这个链接通常用[[Prototype]]
表示,在代码中可以通过__proto__
访问,但__proto__
已不推荐使用)。例如:
function Person() {}
let person = new Person();
console.log(person.__proto__ === Person.prototype); // true
- 原型对象本身也是一个对象,它也有自己的
[[Prototype]]
,这样就形成了一条链,称为原型链。原型链的顶端是Object.prototype
,Object.prototype
的[[Prototype]]
为null
。
属性查找过程举例
- 假设有如下代码:
function Animal() {
this.species = '动物';
}
function Dog() {
this.name = '小狗';
}
Dog.prototype = Object.create(Animal.prototype);
Dog.prototype.constructor = Dog;
let myDog = new Dog();
- 当查找
myDog
的属性时:
- 首先在
myDog
自身上查找。例如查找myDog.name
,由于myDog
自身有name
属性,所以直接返回'小狗'
。
- 如果在
myDog
自身没有找到,就会沿着原型链向上查找,到Dog.prototype
。例如查找myDog.species
,myDog
自身没有species
属性,就到Dog.prototype
查找,Dog.prototype
也没有,继续向上查找。
- 接着到
Animal.prototype
查找,这里找到了species
属性,所以返回'动物'
。
- 如果一直到
Object.prototype
都没有找到,就返回undefined
。例如查找myDog.age
,最终会返回undefined
。