JavaScript 原型和原型链 | 青训营

69 阅读3分钟

复习前期沸点打卡的原型和原型链,顺便记录一下笔记写写感想和学习总结,主要参考了《深入学习js之——原型和原型链#1》《一篇搞定令人疑惑的原型和原型链》

1. 关于 prototype、__proto__ 、constructor

1.1 prototype

prototype是构造函数与原型联系的纽带,构造函数的prototype(显示原型)指向原型对象。通过[构造函数].prototype可以访问到原型,进而通过原型访问实例对象上不存在,但在原型上存在的属性(共享属性)。

函数的prototype属性指向了一个对象,该对象是调用该构造函数而创建的实例的原型,在例子中也是person1和person2的原型。

function Person() {

}
// prototype 是函数才会有的属性 

Person.prototype.name = "Kevin";
var person1 = new Person();
var person2 = new Person();

console.log(person1.name) // Kevin
console.log(person2.name) // Kevin

那么问题来了,什么是原型?

可以这样理解:每一个JavaScript对象(null除外)在创建的时候就会与之关联另外一个对象,这个对象就是我们所说的原型,而每一个对象都会从原型"继承"属性。

1.2 __proto__

__proto__ 作为实例对象和实例原型的之间的链接桥梁,[实例对象].\_\_proto\_\_(隐式原型)指向原型对象。

function Person() {

}

var person = new Person();
console.log(person.__proto__ === Person.prototype); //true;

从上述代码可以看出,构造出的实例对象的__proto__的指向和构造函数的prototype的指向是一致的,两者都指向实例原型。

1.3 constructor

constructor是原型和构造函数之间的联系。[原型].constructor指向与之对应的构造函数。

2. 原型链

在JavaScript中,当读取实例的属性时,如果找不到,就会查找与对象关联的原型中的属性,如果还查不到,就去找原型的原型,一直找到最顶层为止。

为了实现属性的继承共享,需要实现一条共享的链路。

在Javascript中,由构造函数创建的对象,其隐式原型指向构造函数的显示原型,也就是相对应的原型对象。而该原型对象本质上的对象,是通过Object()构造函数构造的,因此该原型对象的隐式原型指向Object()函数的显示原型也就是Object.prototype。Object.prototype本质上也是一个对象,但在网上找该对象的隐式原型会发现结果为null。也就是表示“没有对象”的意思,即Object.prototype是没有原型的。

原型链的就是按照上述描述,从实例对象到相应的原型,再到Object函数的显示原型,直到找不到原型对象的Object.prototype的原型为止的一条链型关系。

原型链是实现属性共享的重要组成部分。

3. 总结

原型是指由构造函数创造出来的实例对象的共同祖先(本质上是一个对象),通过构造函数创造出的实例对象都能继承到该实例原型的属性和方法。

原型链是基于 prototype 、__proto__ 、constructor 连接的,从实例对象到实例原型再到实例原型的原型..以及往上寻找直到原型为null为止的链型关系。