Web前端必知篇:原型链的讲解
js中的数据类型
js中的数据类型有两种,1是基本数据类型,2是引用数据类型。引用数据类型又可分为原生引用类型和自定义引用类型。如下图所示:
js数据类型
引用类型的值(对象)是引用类型的一个实例,引用类型是一种数据结构,描述的是一类对象所具有的属性和方法。每个对象是基于一个引用类型创建的,这个引用类型可以是原生类型,也可以是开发人员定义的类型。ECMAScript提供了Object、Array等原生引用类型,以便开发人员用以实现常见的计算任务。像Object和Array这样的原生构造函数,在运行时会自动出现在执行环境中,此外也可以创建自定义的构造函数,从而定义自定义对象类型的属性和方法。
说到这里,也介绍一下自己,我是一名从事5年的前端开发全栈工程师,如果有想要学习前端的同学,关注小编头条号(点击头像加关注),私信【学习】即可免费领取一整套系统的前端学习教程!
创建对象
创建对象的方法有多种,其中有一种是原型模式。我们创建的每个函数都有一个prototype(原型)属性,这个属性是一个指针,指向一个对象,而这个对象的用途就是包含可以由特定类型的所有实例共享的属性和方法。如果按照字面意思来理解,那么prototype就是通过调用构造函数而创建的那个对象实例的原型对象。举例:
示例
在此,我们将sayName()方法和所有的属性直接添加到了Person的prototype属性中,构造函数变成了空函数。但是仍然可以通过构造函数来创建新对象,而且新对象还会具有相同的属性和方法。这些属性和方法是由所有实例共享的。
理解原型对象
无论什么时候,只要创建了一个新函数,就会根据一组特定的规则为该函数创建一个prototype属性,这个属性指向函数的原型对象。在默认情况下,所有的原型对象都会自动获得一个constructor(构造函数)属性,这个属性包含一个指向prototype属性所在函数的指针。当调用构造函数创建一个实例后,该实例的内部将包含一个指针(内部属性),指向构造函数的原型对象。
示例
上图展示了Person构造函数、Person的原型属性以及Person现有的两个实例之间的关系。在此,Person.prototype指向了原型对象,而Person.prototype.constructor又指回了Person。
原型链
回顾一下构造函数、原型和实例的关系:每个构造函数都有一个原型对象,原型对象都包含一个指向构造函数的指针,而实例都包含一个指向原型对象的内部指针。那么,假如我们让原型对象等于另一个类型的实例,结果会怎么样呢?显然,此时的原型对象将包含指向另一个原型的指针,相应地,另一个原型中也包含着指向另一个构造函数的指针。假如另一个原型又是另一个类型的实例,那么上述关系依然成立,如此层层递进,就构成了实例与原型的链条。这就是原型链的基本概念。
怎么实现原型链?
实现原型链有一种基本模式,如下图:
示例
这个例子中的实例以及构造函数和原型之间的关系如下图:
示例
另外,我们知道,所有的引用类型都继承了Object,而这个继承也是通过原型链实现的。所以上面例子中展示的原型链还应该包括另外一个继承层次,下图展示了该例子中完整的原型链:
示例
SubType继承了SuperType,而SuperType继承了Object。当调用instance.toString()时,实际上调用的是保存在Object.prototype中的那个方法。