JavaScript-原型和原型链

原型和原型链

prototype

在JavaScript中,所有的函数都有一个prototype属性,该属性指向该函数的原型对象

1
2
3
4
5
6
7
8
function Person(name){
this.name = name;
}
Person.prototype.name = 'kerwin';
let p1 = new Person();
let p2 = new Person();
console.log(p1.name);// kerwin
console.log(p2.name);// kerwin

函数的prototype指向的就是对象原型,这个对象是调用构造函数时创建实例的原型对象,就是说p1p2的原型对象是同一个

_proto_

每个对象都会有一个属性,叫做_proto_,该属性指向该对象的原型对象,也就是构造函数的原型属性指向的对象

constructor

每个原型都有一个constructor属性,指向该对象的构造函数

1
2
3
4
5
6
7
8
9
10
function Person(){

}
let person = new Person();
console.log(Person.prototype._proto_ ==== Person);// true
console.log(person._proto_ === Person.prototype);// true
// 在person中找不到constructor属性,所以向上在原型中找到该属性
console.log(person.constructor === Person);// true
console.log(person.constructor === Person.prototype.constructor);
console.log(person.constructor === person._proto_.constructor)

实例与原型

当读取实例中的属性的时候,如果不存在该属性,则会去查找该对象的原型对象中是否存在该属性,如果不存在,则一直向上查找,一直找到最顶部为止

1
2
3
4
5
6
7
8
9
10
function Person(age){
this.age = age;
}
Person.prototype.name = 'zhima';
let p1 = new Person();
person.name = 'kerwin'
console.log(p1.name);// kerwin
// 删除person对象中的name属性
delete person.name
console.log(p1.name);// zhima

可以看到p1的name属性

显示输出了自身的属性值kerwin

当删除了对象中name属性之后,输出的是原型中的数据

原因是当对象内部不存在该属性的时候,会向上在原型中找属性,所以会输出kerwin

原型的原型

原型是随着使用构造函数创建对象时,生成的一个对象。

那么原型也是一个对象,既然是一个对象,那么它一定也有原型

它的原型其实是通过Object对象的构造函数创建的

原型链

简单回顾一下之前的知识点,

prototype是每个函数的一个属性,指向原型对象

_proto_是每一个对象的一个属性,指向原型对象

constructor是每一个原型对象的一个属性,指向其绑定的构造函数

1
每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么假如我们让原型对象等于另一个类型的实例,结果会怎么样?显然,此时的原型对象将包含一个指向另一个原型的指针,相应的,另一个原型中也包含着一个指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立。如此层次递进,就构成了原型和实例的链条,这就是所谓的原型链的概念                                                              ----------《摘自JavaScript高级程序设计》

那Object.prototype的原型是什么呢?是null

图中蓝色的线就是原型链

给作者买杯咖啡吧~~~