原型、原型链

198 阅读2分钟

一、原型

什么是原型?

首先需要清楚一个概念,在JavaScript中,在使用ES6以前并没有class(类)的概念,在JavaScript中并不能使用类的形式来创建实例,而是使用构造函数的形式。

prototype:在JavaScript中,我们创建的每个函数都有一个 prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么 prototype 就是通过调用构造函数而创建的那个对象实例的原型对象。使用原型对象的好处是可以让所有对象实例共享它所包含的属性和方法。

构造函数和原型:当调用构造函数创建一个新实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象,所以这个实例会继承构造函数中的所有属性。

关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。

prototype 和 proto

每个对象都有一个__proto__属性,并且指向它的prototype原型对象

每个构造函数都有一个prototype原型对象,prototype原型对象里的constructor指向构造函数本身

二、原型链

原型链概念:设想原型对象等于另一个类型的实例此时的原型对象将包含一个指向另一个原型的指针,相应地,另一个原型中也包含着一个向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这种依次递进的方式可以形象的称为原型链。

理解原型链:

在这样一个数组中使用了valueOf()方法,但是在他自身Array.prototype对象里去找,但是你会发现arr.____proto____上没有valueOf方法。那这个方法在哪呢?

位于Array.prototype.____proto____中。 原因:当试图访问一个对象的属性时,它不仅仅在该对象上搜寻,还会搜寻该对象的原型,以及该对象的原型的原型,依次层层向上搜索,直到找到一个名字匹配的属性或到达原型链的末尾。

arr ---> Array.prototype ---> Object.prototype ---> null

所以上述举例的查找流程可以简单理解为:

  1. 当前实例对象obj,查找obj的属性或方法,找到后返回
  2. 没有找到,通过obj. proto,找到obj构造函数的prototype并且查找上面的属性和方法,找到后返回
  3. 没有找到,把Array.prototype当做obj,重复以上步骤,查找到Object.prototype时 Object.prototype.proto === null,意味着查找结束