【重点】图解:告诉面试官什么是 JS 原型和原型链?

在这里插入图片描述

写在前边

在我初学 JS 语言的继承机制原型和原型链的时候,我一直理解不了这种设计机制,再加上以前原有对 Java继承的理解,在学习 JS 继承机制的设计上踩了一个大坑,不少知识点前期都是死记硬背,没法真正的理解它的设计思想。前端

JS 中的继承机制思想能够说是学习 JS 的一个核心思想,更能够说是 JS 中的一个命脉,每每这些复杂、抽象的继承关系,以及专业术语、代名词确成为了困扰初学者的绊脚石。当我真正理解它的设计思想时,其实并无那么复杂,并且以为很是简单。面试

在写这篇 JS 的原型和原型链的文章以前,我在谷歌搜索检索了大量的高赞有关 JS 原型和原型链的文章,大部分都是围绕着“是什么”来说的,致使部分初学者缺乏对 JS 继承的设计与实现的先后关联性,仍是很难准确的去理解。算法

咱们先要明白,学习这块内容知识要知道设计者“ 为何这样作 ” 远比 “怎么作的” 重要的多这才是掌握这部份内容的关键。编程

今天小鹿对 JS 的继承机制要作一个系统的总结,从设计者的角度出发,将复杂的设计思想用动画呈现,将零碎的知识点体系化,争取让你一文搞懂 JS 的继承机制思想(原型和原型链)。浏览器

思惟导图

在这里插入图片描述

一、JS 的发展史

要想贯彻 JS 的核心设计思想,咱们要从 JS 的诞生提及。服务器

1.1 为何会诞生 JavaScript ?

相对比较成熟的浏览器是由网景公司发布的,早些年间,浏览器只能浏览网页内容,而不能进行用户交互。好比咱们登陆输入用户名和密码,在浏览器是不能进行判断用户是否真正输入了,而是经过服务器来判断,若是没有输入,返回错误提示用户,这种设计很是的浪费时间和服务器资源。 网络

在这里插入图片描述
为了解决这个问题,网景公司须要开发一种运行在浏览器中的脚本语言,用来简单的作用户输入校验等操做。

当时最流行的语言是面向对象的Java编程语言 ,网景公司为了可以借助 Java将浏览器脚本语言流传开,因此起名 JavaScript。其实二者没有任何的关系。数据结构

1.2 存在的问题

JS 中的数据类型设计受当时 Java流行的影响,都是对象类型,这时候就遇到问题了,有对象必然涉及到继承机制,那么 JS 的继承机制要设计成 Java同样呢?仍是另有设计思想?编程语言

二、JS 继承的设计思想

JS 的开发者想若是设计成像 Java同样有“类”的概念岂不是和 Java同样成为了一种彻底面向对象的编程语言了?最后决定本身设计一种继承机制,可是它的设计思想仍是采用了 Java的一些特性。函数

2.1 生成对象

一般 Java 生成对象是经过 new 的方式,经过类生成一个实例对象的过程。可是 JS 中并无类,那 JS 的设计者要怎么作?

在这里插入图片描述
他找到了 Java 和 JS 的共同点就是二者都有构造函数, Java的 new 的过程内部其实调用了构造函数。可是 JS 是没有“类”的概念的,因而 JS 就把 new 一个“类”设计成了 new 一个构造函数,因而构造函数成为了一个实例对象的原型对象。
在这里插入图片描述

三、为何要设计原型对象?

上述这样的原型设计有一个致命的缺点就是没法共享公共属性。

由于咱们知道,每 new 一个对象,生成的实例是两个不一样的对象。因此共有的属性也不是共享的,若是咱们改动一个对象的 type 属性,可是另外一个不会改变,由于这个属性没有共享。

因此要设计一个对象专门用来存储对象共享的属性,那么咱们叫它「 原型对象」。

四、什么是原型对象?

要想让构造函数生成的全部实例对象都可以共享属性,那么咱们就给构造函数加一个属性叫作prototype,用来指向原型对象,咱们把全部实例对象共享的属性和方法都放在这个构造函数的prototype属性指向的原型对象中,不须要共享的属性和方法放在构造函数中。

这里有一点疑惑就是,咱们知道对象能够设置属性,函数也能够设置属性吗?对于初学者来讲是比较懵逼的,那咱们能够稍微的简单说一下:

JavaScript 中的函数拥有对象的全部能力,也所以可被称做为任意其余类型对象来对待。当咱们说函数是第一类对象的时候,就是说函数也可以对象的一些功能,好比添加属性,函数当作参数传递等。

因此说,实例对象一旦经过构造函数建立,就会自动给实例对象赋值上原型对象上共享的属性或方法。说清楚一点就是该对象属性都指向了原型对象的属性值。

在这里插入图片描述

五、对象和函数在原型链关系?

在这里插入图片描述

上述的图反映了对象以及函数在原型链中的关系,若是你觉的上边的这张图看懵逼了,不要紧,我刚开始学习原型链的时候,根本不知道上边这是什么“清明上河图”,小鹿下面经过一步步的拆分讲解,看这张图就很是简单,没错,很是简单。

咱们文章的开头也说了什么是原型对象,说白了就是构造函数的一个 prototype 属性,这个属性就指向原型对象。

其实咱们其中一些链接属性没有讲到,只讲到了prototype 属性,下面一张图来将剩下的属性补充完整,咱们只要把这张图印到大脑中就能够了。

在这里插入图片描述

咱们来分析一下上图,首先咱们先要声明一个狗的构造函数,定义其名字和体重属性(私有属性),同时每一个构造函数咱们上边讲到了,都会有一个prototype属性。

在这里插入图片描述

这个prototype指向的就是原型对象,原型对象放的就是对象共享的属性。可是注意,原型对象里有一个constructor属性,这个属性又指回了构造函数。

在这里插入图片描述

在 JS 全部对象中,只要是对象,都会有一个内置属性叫作_proto_,并且这个属性是系统自动生成的,只要你建立一个对象,这个对象就有这个属性。这个_proto_属性指向的是原型对象。

经过上边的分布讲解,咱们明白了构造函数与对象实例以及原型对象的关系。

总结为一句话为:

构造函数的 prototype 指向原型对象,原型对象有一个 constructor 属性指回构造函数,每一个构造函数生成的实例对象都有一个 proto 属性,这个属性指向原型对象。

没错,原型就是这么简单。可是你会发现,原型也是对象呀,你说只要是对象都会有一个_proto_属性指向自身构造函数的原型对象。

没错,要想知道原型对象的_proto_属性指向谁,就要知道是哪一个构造函数建立了原型对象?

咱们知道,全部的 JS 对象的都是继承了一个叫作 Object 的对象。能够理解为 Object构造函数创造了这个万物,他们的关系以下,和上边是一样的道理,上边总结的那句话好好理解一下。

在这里插入图片描述

可是上图中会有一个疑问,Object构造函数原型对象的也是对象,它确定也有一个_proto_属性,为何会指向null 呢?

咱们在拿上述总结的那句话,_proto_属性指向的是自身构造函数的原型对象,自身的构造函数是谁?是 Object构造函数,那 Object构造函数的原型是谁?固然是自己(如图),因此把_proto_指向了null

上边的关系若是不仔细整理的话确实很乱,尤为是对于初学者,可是若是像小鹿这样已整理,再乱的关系把它安排的层次分明,没有理解,就多看几篇文章。

六、原型链

咱们还有一个问题没有解决就是原型链?既然我么你知道什么是原型了,原型链是什么?顾名思义,确定是一条链,既然每一个对象都有一个_proto_属性指向原型对象,那么原型对象也有_proto_指向原型对象的原型对象,直到指向上图中的null,这才到达原型链的顶端。

不要忘了,上边那种图咱们尚未把它理解,咱们把图自上而下理解。

在这里插入图片描述
第一张图分解,上边小鹿画的图的关系和这个同样的,仔细对比一下,很简单,第一张图就这么解决了。
在这里插入图片描述
咱们继续向下分割,看第二张图。
在这里插入图片描述
第二张图怎么仍是那么眼熟呢,这不是小鹿上边分析的 Object的关系图吗?对的,没错。
在这里插入图片描述
第三张图,稍微绕个弯子,可是换汤不换药呀,听小鹿分析来。
在这里插入图片描述
看着仍是眼熟,只不过把 function换成了 Function,f 变成了大写的 F,这里涉及到一个知识点就是,在 JS 中,全部的 function函数都是由 Function继承来的,能够说是 Function是全部 function的祖宗。

Function是由谁生产来的?咱们看到图中的Function函数有_proto_属性了,并且属性指向本身的原型对象,那不就是本身繁衍本身吗?能够这么理解。

小结

这里咱们在纵观全图,总结几条定义你比对着图去找。

一、全部的实例的_proto_都指向该构造函数的原型对象(prototype)。

二、全部的函数(包括构造函数)是Function的实例,因此全部函数的_proto_的都指向Function的原型对象。

三、全部的原型对象(包括 Function的原型对象)都是Object的实例,因此_proto_都指向 Object(构造函数)的原型对象。而Object构造函数的 _proto_指向 null。

四、Function构造函数自己就是Function的实例,因此_proto_指向Function的原型对象。

全篇文章的精华都在最后的总结部分,前边的全部分解讲解是为了让你理解这些函数对象以及原型对象之间的关系,这关系都是固定的,谁指向谁,都是写死额,只要你记住了他们的关系,这张图就理解的差很少了,可以理解完这张图,你的原型和原型链已经了解的很扎实了,可是还须要作一些面试题巩固一下。

后期会出文章专门讲解怎么解决大厂的这种有关原型和原型链的面试题。

今天的文章就到这里了,今天的内容看起来多,其实总结起来就几句话,仍是那句话,原创不易,点个赞就是对原创做者最大的支持,很是感谢。


❤️ 不要忘记留下你学习的脚印 [点赞 + 收藏 + 评论]

文章都看完了,为什么不妨点个赞呢?嘻嘻,那就说明你很自私,你怕那么好的文章让别人也看到。开个小小玩笑。

其实我也很自私,我把个人一直以来坚持原创的公众号:「小鹿动画学编程」偷偷给你,里边汇聚了小鹿以动画形式讲解的数据结构与算法、网络原理、Web 等技术文章。

做者Info:

【做者】:小鹿

【原创公众号】小鹿动画学编程

【简介】:和小鹿同窗一块儿用动画的方式从零基础学编程,将Web前端领域、数据结构与算法、网络原理等通俗易懂的呈献给小伙伴。公众号回复 “资料” 送一从零自学资料大礼包!

【转载说明】:转载请说明出处,谢谢合做!~

相关文章
相关标签/搜索