图解:什么是 JS 原型和原型链?

2023-01-03 0 580

图解:什么是 JS 原型和原型链?

责任编辑风险提示QQ社会公众号「白鸽动画电影学程式设计」,译者不免理想的码农。转发责任编辑请联络白鸽动画电影学程式设计社会公众号。

写在前面

在我算数 JS 词汇的承继监督机制蓝本和蓝本链的时候,我一直认知没法这种结构设计监督机制,再加之以后旧有对 Java承继的认知,在自学 JS 承继监督机制的结构设计上踩了两个深坑,许多习题后期都是做题,难以或者说的认知它的结构设计价值观。

JS 中的承继监督机制价值观能说是自学 JS 的两个核心理念价值观,更能说是 JS 中的两个生命线,常常这些繁杂、抽象化的承继亲密关系,以及专有名词、同义词却成为了所苦新手的拦路虎。当我或者说认知它的结构设计价值观时,只不过并没有那么繁杂,而且真的比较简单。

在写这篇 JS 的蓝本和蓝本链的该文以后,我在Google搜寻索引了大批的高赞相关 JS 蓝本和蓝本链的该文,绝大部分都是紧紧围绕着“是甚么”来说的,引致部分新手缺乏对 JS 承继的结构设计与同时实现的其间相关性,还是极难精确的去认知。

他们先要知道,自学那块文本科学知识要知道结构斯特默“ 为甚么这样做 ” 相比而言 “怎么做的” 重要的多这才是掌控该些文本的关键性。

那时白鸽对 JS 的承继监督机制要做两个控制系统的归纳,从结构斯特默的视角起程,将繁杂的结构设计价值观用动画电影呈现出,将零散的习题控制系统化,谋求让你该文比如说 JS 的承继监督机制价值观(蓝本和蓝本链)。

观念填空

图解:什么是 JS 原型和原型链?

1.JS 的文化史

要想全面落实 JS 的核心理念结构设计价值观,他们要从 JS 的问世讲起。

1.1 为甚么会问世 JavaScript ?

相对比较成熟的浏览器是由网景公司发布的,早些年间,浏览器只能浏览网页文本,而不能进行用户交互。比如他们登录输入用户名和密码,在浏览器是不能进行判断用户是否或者说输入了,而是通过服务器来判断,如果没有输入,返回错误提示用户,这种结构设计非常的浪费时间和服务器资源。

图解:什么是 JS 原型和原型链?

为了解决这个问题,网景公司需要开发一种运行在浏览器中的脚本词汇,用来简单的做用户输入校验等操作。

当时最流行的词汇是面向对象的Java程式设计词汇 ,网景公司为了能够借助 Java将浏览器脚本词汇流传开,所以起名 JavaScript。只不过两者没有任何的亲密关系。

1.2 存在的问题

JS 中的数据类型结构设计受当时 Java流行的影响,都是对象类型,这时候就遇到问题了,有对象必然涉及到承继监督机制,那么 JS 的承继监督机制要结构设计成 Java一样呢?还是另有结构设计价值观?

2.JS 承继的结构设计价值观

JS 的开发者想如果结构设计成像 Java一样有“类”的概念岂不是和 Java一样成为了一种完全面向对象的程式设计词汇了?最后决定自己结构设计一种承继监督机制,但是它的结构设计价值观还是采用了 Java的一些特性。

2.1 生成对象

通常 Java 生成对象是通过 new 的方式,通过类生成两个实例对象的过程。但是 JS 中并没有类,那 JS 的结构斯特默要怎么做?

图解:什么是 JS 原型和原型链?

他找到了 Java 和 JS 的共同点就是两者都有构造函数, Java的 new 的过程内部只不过调用了构造函数。但是 JS 是没有“类”的概念的,于是 JS 就把new 两个“类”结构设计成了 new 两个构造函数,于是构造函数成为了两个实例对象的蓝本对象。

图解:什么是 JS 原型和原型链?

3.为甚么要结构设计蓝本对象?

上述这样的蓝本结构设计有两个致命的缺点就是难以共享公共属性。

因为他们知道,每 new 两个对象,生成的实例是两个不同的对象。所以共有的属性也不是共享的。

图解:什么是 JS 原型和原型链?

所以要结构设计两个对象专门用来存储对象共享的属性,那么他们叫它「蓝本对象」。

4.甚么是蓝本对象?

要想让构造函数生成的所有实例对象都能够共享属性,那么他们就给构造函数加两个属性叫做prototype,用来指向蓝本对象,他们把所有实例对象共享的属性和方法都放在这个构造函数的prototype属性指向的蓝本对象中,不需要共享的属性和方法放在构造函数中。

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

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

所以说,实例对象一旦通过构造函数创建,就会自动给实例对象赋值上蓝本对象上共享的属性或方法。说清楚一点就是该对象属性都指向了蓝本对象的属性值。

图解:什么是 JS 原型和原型链?

5.对象和函数在蓝本链亲密关系?

图解:什么是 JS 原型和原型链?

上述的图反映了对象以及函数在蓝本链中的亲密关系,如果你真的上边的这张图看懵逼了,没亲密关系,我刚开始自学蓝本链的时候,根本不知道上边这是甚么“清明上河图”,白鸽下面通过一步步的拆分讲解,看这张图就比较简单,没错,比较简单。

他们该文的开头也说了甚么是蓝本对象,说白了就是构造函数的两个 prototype属性,这个属性就指向蓝本对象。

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

图解:什么是 JS 原型和原型链?

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

图解:什么是 JS 原型和原型链?

这个prototype指向的就是蓝本对象,蓝本对象放的就是对象共享的属性。但是注意,蓝本对象里有两个constructor属性,这个属性又指回了构造函数。

图解:什么是 JS 原型和原型链?

他们通过 new 构造函数生成两个狗的对象实例,两个叫豆豆,两个叫贝贝,这两个是两个不同的对象,名字体重都不相同,但是他们会共享蓝本对象上的属性 type,它们共有的属性都是犬类。

图解:什么是 JS 原型和原型链?

在 JS 所有对象中,只要是对象,都会有两个内置属性叫做_proto_,而且这个属性是控制系统自动生成的,只要你创建两个对象,这个对象就有这个属性。这个_proto_属性指向的是蓝本对象。

通过上边的分布讲解,他们知道了构造函数与对象实例以及蓝本对象的亲密关系。

归纳为一句话为:

构造函数的 prototype 指向蓝本对象,蓝本对象有两个 constructor 属性指回构造函数,每个构造函数生成的实例对象都有两个 _proto_ 属性,这个属性指向蓝本对象。

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

没错,要想知道蓝本对象的_proto_属性指向谁,就要知道是哪个构造函数创建了蓝本对象?

他们知道,所有的 JS 对象的都是承继了两个叫做 Object 的对象。可以认知为Object 构造函数创造了这个万物,他们的亲密关系如下,和上边是同样的道理,上边归纳的那句话好好认知一下。

图解:什么是 JS 原型和原型链?

但是上图中会有两个疑问,Object 构造函数蓝本对象的也是对象,它肯定也有两个_proto_属性,为甚么会指向 null 呢?

他们在拿上述归纳的那句话,_proto_属性指向的是自身构造函数的蓝本对象,自身的构造函数是谁?是 Object 构造函数,那 Object构造函数的蓝本是谁?当然是本身(如图),所以把_proto_指向了null。

上边的亲密关系如果不仔细整理的话确实很乱,尤其是对于新手,但是如果像白鸽这样已整理,再乱的亲密关系把它安排的井井有条,没有认知,就多看几篇该文。

6.原型链

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

不要忘了,上边那种图他们还没有把它认知,他们把图自上而下认知。

图解:什么是 JS 原型和原型链?

第一张图分解,上边白鸽画的图的亲密关系和这个一样的,仔细对比一下,很简单,第一张图就这么解决了。

图解:什么是 JS 原型和原型链?

他们继续向下分割,看第二张图。

图解:什么是 JS 原型和原型链?

第二张图怎么还是那么眼熟呢,这不是白鸽上边分析的 Object 的亲密关系图吗?对的,没错。

图解:什么是 JS 原型和原型链?

第三张图,稍微绕个弯子,但是换汤不换药呀,听白鸽分析来。

图解:什么是 JS 原型和原型链?

看着还是眼熟,只不过把function换成了Function,f 变成了大写的 F,这里涉及到两个习题就是,在 JS 中,所有的 function函数都是由Function承继来的,能说是Function是所有 function的祖宗。

那Function是由谁生产来的?他们看到图中的Function函数有_proto_属性了,而且属性指向自己的蓝本对象,那不就是自己繁衍自己吗?能这么认知。

小结

这里他们在纵观全图,归纳几条定义你比对着图去找。

1、所有的实例的_proto_都指向该构造函数的蓝本对象(prototype)。

2、所有的函数(包括构造函数)是Function的实例,所以所有函数的 _proto_的都指向Function的蓝本对象。

3、所有的蓝本对象(包括 Function的蓝本对象)都是Object的实例,所以_proto_都指向 Object(构造函数)的蓝本对象。而 Object构造函数的 _proto_指向 null。

4、Function构造函数本身就是 Function 的实例,所以_proto_指向Function的蓝本对象。

全篇该文的精华都在最后的归纳部分,前面的所有分解讲解是为了让你认知这些函数对象以及蓝本对象之间的亲密关系,这亲密关系都是固定的,谁指向谁,都是写死额,只要你记住了他们的亲密关系,这张图就认知的差不多了,能够认知完这张图,你的蓝本和蓝本链已经了解的很扎实了,但是还需要做一些面试题巩固一下。

相关文章

发表评论
暂无评论
官方客服团队

为您解决烦忧 - 24小时在线 专业服务