Skip to content

原型链详细图解

了解内容

画原型链之前需要先了解什么叫构造函数、原型、原型对象、实例化对象之间的关系

构造函数

通过new函数名来实例化对象的函数称之为构造函数,构造函数首字母通常大写,类似系统内置的构造函数:Object,Function,Array,所有函数都可以作为构造函数。

实例化对象

实例化对象就是通过构造函数new出来的对象,对象出生就有一条隐形的属性__proto__指向构造函数的原型对象

原型

原型是一个对象,是函数的一个特殊属性prototype,指针指向原型对象,通过这个函数new出来的实例对象可以通过继承获取原型上的所有属性和方法。

原型对象

原型对象是一个属于其所在的函数的一个空对象,可以添加属性和方法。

原型链

在JavaScript中, 万物皆对象,然而对象和对象之间并不是相互独立存在的,他们之间一定有什么联系,他们联系的方式就是通过原型链,每一个对象都通过原型链继承祖先的属性或方法,直到null结束

__proto__的作用就是指向它的原型对象,也就是通俗来说的父对象。当我们访问一个对象的属性时,对象内没有这个属性,那么就会访问__proto__指向的父对象,若父对象也没有则会继续向上查找,直到顶端null。这就是原型链。

所有的函数都是对象,所以称之为函数对象

原型链全貌

原型链全貌图1

原型链全貌图2

在上面这个例子中的a对象的原型链结构图如下:

a => A.protorype => Object.protype => Null

对这个实例化对象而言,访问对象的属性,是首先在对象本身去找,如果没有,就会去他的原型对象中找,一直找到原型链的终点;如果是修改对象的属性,如果这个实例化对象中有这个属性,就修改,没有这个属性就添加这个属性。

__proto__的作用就是指向它的构造函数的原型对象,也就是通俗来说的父对象。当我们访问一个对象的属性时,对象内没有这个属性,那么就会访问__proto__指向的父对象,若父对象也没有则会继续向上查找,直到顶端null。这就是原型链。

难点

  1. Function构造函数可以用Function.__proto__来访问Function.prototype,因为Function构造函数的构造函数是自己,作为实例化对象的角色来访问自己的原型对象,访问的就是Function构造函数的原型对象,所以Function.__proto__Function.prototype是同一个人

原型链详细图解插图2

2.任何函数都是函数,他都会继承Function函数的所有属性和方法,而Function是内置的构造函数,也是对象,也会继承Object所有的属性和方法。

3.Object.prototype的原型指向Null

区别

  1. 属性不同:Prototype是构造函数的属性,__proto__是对象的属性。
  2. 内容不同:如果没有Prototype,那么共用属性就没有立足之地;如果没有__proto__,那么一个对象就不知道自己的共用属性有哪些。

__proto__指向

  1. 所有函数对象的__proto__都指向Function的原型对象
  2. 所有实例对象的__proto__都指向他的构造函数的原型对象
  3. Object的原型对象的__proto__指向null
  4. 除了Object的原型对象,其他所有的原型对象中__proto__都指向Object的原型对象

拆解

新手看上面的已经要绕晕了,现在我们拆开来分析一下原型链

此处以构造函数A为演示

构造函数和实例对象和原型对象的关系

只要定义了一个函数,天生会自带一个prototype属性,这个属性会指向函数的原型对象

原型对象和构造函数的关系就是,构造函数天生就有一个prototype属性,通过这个属性就能访问原型对象

原型对象就像一个公共的区域,同一个构造函数实例化出来的对象,都可以访问到这个原型对象

每个实例化对象都有一条__proto__,这条属性指向其构造函数的原型对象

所以实例化对象a__proto__和构造函数Aprototype指向的地方是一致的,都是构造函数Aprototype原型对象

很明显,他们是一个三角恋关系,只要构造函数实例化了一个对象,那么就一定会形成三角恋关系

原型链详细图解插图3

原型链详细图解插图4

构造函数的原型对象和Object的关系

任何一个对象都是由Object构建的,原型对象也不例外,所以Object是构造函数A的原型对象的构造函数

那么,Object实例化了构造函数A的原型对象,那么构造函数A的原型对象和Object也有链式关系

构造函数A__proto__就会指向Object.prototype,所以图片再添加上ObjectObject.prototype,那么原型链就会变成这样

原型链详细图解插图5

根据上图的原型链来看,那么构造函数A的原型对象的__proto__和Object.prototype就是同一个人

原型链详细图解插图6

Object原型对象的__proto__

正常来说,只要是原型对象,就会有他的__proto__,如果Object的原型对象的__proto__不指向为null的话

那么整个原型链就会一直往上查找,无休无止,那不就乱套了吗,所以Object.prototype.__proto__指向null

原型链详细图解插图7

原型链详细图解插图8

Function和Object

首先,FunctionObject都是构造函数,而所有的构造函数都是Function这个构造函数实例化的,因此FunctionObject的构造函数,那么Object.__proto__会指向Function.prototype

其次,Function.prototype是一个实例对象,对象都是Object这个构造函数实例化出来的,那么Function.prototype会指向Object.prototype

Function__proto__比较特殊,他也是指向自己的原型对象

因此,

Object.__proto__ === Function.prototypeFunction.prototype.__proto__===Object.prototypeFunction.__proto__===Function.prototype

原型链详细图解插图9

因此,图片再加上这几条

原型链详细图解插图10

Function和构造函数

所有构造函数都是Function实例化出来的,那么既然是实例化出来的,就会形成三角恋,那么把A和Function的三角恋关系加上之后,整个图片就完整了

原型链详细图解插图11

艾雨博客微信公众号二维码
© 版权声明
文章版权归作者所有,未经允许请勿转载.
本站资源多数存于云盘,如有失效请邮件联系我.
本网站的文章部分内容可能来源于网络,如有侵权,请联系884684993#qq.com进行删除处理.