帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)

转载自  帮你彻底搞懂JS中的prototype、__proto__与constructor(图解)
  作为一名前端工程师,必须搞懂JS中的prototype、__proto__与constructor属性,相信很多初学者对这些属性存在许多困惑,容易把它们混淆,本文旨在帮助大家理清它们之间的关系并彻底搞懂它们。这里说明一点,__proto__属性的两边是各由两个下划线构成(这里为了方便大家看清,在两下划线之间加入了一个空格:_ _proto_ _),实际上,该属性在ES标准定义中的名字应该是[[Prototype]],具体实现是由浏览器代理自己实现,谷歌浏览器的实现就是将[[Prototype]]命名为__proto__,大家清楚这个标准定义与具体实现的区别即可(名字有所差异,功能是一样的)。
 

本文基于谷歌浏览器(版本 72.0.3626.121)的实验结果所得。

我们从如下一个简单的例子展开讨论,并配以相关的图帮助理解:

function Foo() {...};
let f1 = new Foo();

以上代码表示创建一个构造函数Foo(),并用new关键字实例化该构造函数得到一个实例化对象f1。虽然是简简单单的两行代码,然而它们背后的关系却是错综复杂的,如下图所示:

看到这图别怕,让我们一步步剖析,彻底搞懂它们!

图的说明:右下角为图例,红色箭头表示__proto__属性指向、绿色箭头表示prototype属性的指向、棕色实线箭头表示本身具有的constructor属性的指向,棕色虚线箭头表示继承而来的constructor属性的指向;蓝色方块表示对象,浅绿色方块表示函数(这里为了更好看清,Foo()仅代表是函数,并不是指执行函数Foo后得到的结果,图中的其他函数同理)。图的中间部分即为它们之间的联系,图的最左边即为例子代码。

首先,我们需要牢记两点:①\_\_proto\_\_和constructor属性是对象所独有的;② prototype属性是函数所独有的。但是由于JS中函数也是一种对象,所以函数也拥有__proto__和constructor属性,这点是致使我们产生困惑的很大原因之一。上图有点复杂,我们把它按照属性分别拆开,然后进行分析:


第一,这里我们仅留下 __proto__属性,它是对象所独有的,可以看到__proto__属性都是由一个对象指向一个对象,即指向它们的原型对象(也可以理解为父对象),那么这个属性的作用是什么呢?它的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(可以理解为父对象)里找,如果父对象也不存在这个属性,则继续往父对象的__proto__属性所指向的那个对象(可以理解为爷爷对象)里找,如果还没找到,则继续往上找…直到原型链顶端null,此时若还没找到,则返回undefined,由以上这种通过__proto__属性来连接对象直到null的一条链即为我们所谓的原型链。

 

第二,接下来我们看 prototype 属性:


prototype属性,别忘了一点,就是我们前面提到要牢记的两点中的第二点,它是函数所独有的,它是从一个函数指向一个对象。它的含义是函数的原型对象,也就是这个函数(其实所有函数都可以作为构造函数)所创建的实例的原型对象,由此可知:f1.__proto__ === Foo.prototype,它们两个完全一样。那prototype属性的作用又是什么呢?它的作用就是包含可以由特定类型的所有实例共享的属性和方法,也就是让该函数所实例化的对象们都可以找到公用的属性和方法。任何函数在创建的时候,其实会默认同时创建该函数的prototype对象。

 

最后,我们来看一下 constructor 属性:

constructor属性也是对象才拥有的,它是从一个对象指向一个函数,含义就是指向该对象的构造函数,每个对象都有构造函数(本身拥有或继承而来,继承而来的要结合__proto__属性查看会更清楚点,如下图所示),从上图中可以看出Function这个对象比较特殊,它的构造函数就是它自己(因为Function可以看成是一个函数,也可以是一个对象),所有函数和对象最终都是由Function构造函数得来,所以constructor属性的终点就是Function这个函数。


这里解释一下上段中“每个对象都有构造函数”这句话。这里的意思是每个对象都可以找到其对应的constructor,因为创建对象的前提是需要有constructor,而这个constructor可能是对象自己本身显式定义的或者通过__proto__在原型链中找到的。而单从constructor这个属性来讲,只有prototype对象才有。每个函数在创建的时候,JS会同时创建一个该函数对应的prototype对象,而函数创建的对象.__proto__ === 该函数.prototype,该函数.prototype.constructor===该函数本身,故通过函数创建的对象即使自己没有constructor属性,它也能通过__proto__找到对应的constructor,所以任何对象最终都可以找到其构造函数(null如果当成对象的话,将null除外)。如下:

总结一下:

  1. 我们需要牢记两点:①__proto__和constructor属性是对象所独有的;② prototype属性是函数所独有的,因为函数也是一种对象,所以函数也拥有__proto__和constructor属性。
    2.__proto__属性的作用就是当访问一个对象的属性时,如果该对象内部不存在这个属性,那么就会去它的__proto__属性所指向的那个对象(父对象)里找,一直找,直到__proto__属性的终点null,然后返回undefined,通过__proto__属性将对象连接起来的这条链路即我们所谓的原型链。
  2. prototype属性的作用就是让该函数所实例化的对象们都可以找到公用的属性和方法,即f1.__proto__ === Foo.prototype。
  3. constructor属性的含义就是指向该对象的构造函数,所有函数(此时看成对象了)最终的构造函数都指向Function。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/323098.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

ssl1715-计算面积【差积】

正题 题目大意 给一个平行四边形的3个点&#xff0c;求最大面积。 解题思路 明显答案就是差积*2的绝对值。 codecodecode #include<cstdio> #include<algorithm> #include<cmath> #define db double using namespace std; int n; struct node{db x,y; }p[…

ASP.NET Core 企业级开发架构简介及框架汇总

一、 垂直方向架构 1. 多层架构 分层架构通过程序包或者程序的隔离构建松耦合的应用。我们以最近流行的洋葱架构模型进行分析&#xff0c;如图

【Php】最最简单的php环境搭建

Wamp是apachemysqlphp的集成环境&#xff0c;通过一键安装程序&#xff0c;可以完全免除配置的烦恼。 链接&#xff1a; 链接&#xff1a;https://pan.baidu.com/s/1717Mw66Z1wZ67ltLriUVew 提取码&#xff1a;7h5t 下载之后一直下一步&#xff0c;默认默认即可 如果输入local…

01)自学JavaScript

1. JavaScript 简介 1.1 JavaScript 是脚本语言 JavaScript 是一种轻量级的编程语言。 JavaScript 是可插入 HTML 页面的编程代码。 JavaScript 插入 HTML 页面后&#xff0c;可由所有的现代浏览器执行。 2. JavaScript 用法 HTML 中的脚本必须位于 <script> 与 &l…

ssl1213-多边形面积【差积,计算几何】

正题 题目大意 求一个多边形面积。 解题思路 随便定一个原点&#xff0c;然后答案就是相邻点的差积之和的绝对值。 要判断不能组成多边形的情况。 codecodecode #include<cstdio> #include<algorithm> #include<cmath> #define N 1010 #define db double …

Memcached总结

一、介绍 Memcached是一个自由开源的&#xff0c;高性能&#xff0c;分布式内存对象缓存系统。 Memcached是一种基于内存的key-value存储&#xff0c;用来存储小块的任意数据&#xff08;字符串、对象&#xff09;。 目的&#xff1a;通过缓存数据库查询结果&#xff0c;减少…

浅析C#中单点登录的原理和使用

是单点登录&#xff1f; 我想肯定有一部分人“望文生义”的认为单点登录就是一个用户只能在一处登录&#xff0c;其实这是错误的理解&#xff08;我记得我第一次也是这么理解的&#xff09;。 单点登录指的是多个子系统只需要登录一个&#xff0c;其他系统不需要登录了&#xf…

虚拟机和linux的安装

下载地址&#xff1a; 虚拟机14版本的&#xff1a; 链接:https://pan.baidu.com/s/1lxp62gerSI_29wQDuTEAJQ 提取码:53dn 乌班图 https://ubuntu.com/download

Mybatis入门程序增删改查操作

学习目标 了解Mybatis的基本知识熟悉Mybatis的工作原理掌握Mybatis入门程序的编写 文章目录 1.初始Mybatis 2.Mybatis入门程序 3.Mybatis操作总结 1.初始Mybatis MyBatis 是一款优秀的持久层框架&#xff0c;它支持自定义 SQL、存储过程以及高级映射。MyBatis 免除了几乎所…

Memcached:列出所有Key

翻译自 Memcached&#xff1a;列出所有Key 在一般情况下&#xff0c;有没有办法列出所有的Key&#xff0c;一个memcached的实例存储。但是&#xff0c;您可以列出类似于第一个1Meg键的内容&#xff0c;这在开发过程中通常就足够了。这是如何做&#xff1a; Telnet到您的服务…

jzoj5354-导弹拦截【dp,最大匹配,最少路径覆盖】

正题 解题思路 一个东西可以拦截导弹&#xff0c;每次只能打比上一次x,y,zx,y,zx,y,z都大的导弹。求一个最多可以拦截掉多少个导弹和至少要多少个才能拦截完。拦截导弹没有顺序要求。 解题思路 由于没有顺序要求所以我们可以直接定义一个比较&#xff0c;然后第一问做法和导弹…

ASP.NET Core 2.0 全局配置项

问题 如何在 ASP.NET Core 2.0 应用程序中读取全局配置项&#xff1f; 答案 首先新建一个空项目&#xff0c;并添加两个配置文件&#xff1a; 1. appsettings.json { "Section1": { "SettingA": "ValueA", "SettingB": "V…

Auto.JS 教程

最近淘宝双十一活动来了&#xff0c;有个自动领猫币的脚本&#xff0c;基于auto.js&#xff0c;亲测有效。有兴趣的点这里 声明&#xff1a; 本教程基于b站up主-笔青居的视频。传送门&#xff1a;https://space.bilibili.com/21486893/video Auto.JS Auto.js 是个基于 JavaScri…

Mybatis的核心配置

学习目标 了解Mybatis核心对象的作用熟悉Mybatis配置文件中各个元素的作用掌握Mybatis映射文件中常用元素的使用 文章目录 1.Mybatis的核心对象 1.1 SqlSessionFactory 1.2 SqlSession 1.2.1 使用工具类创建SqlSession 2. 配置文件 2.1 主要元素 3. 映射文件 2.1主要元素…

jzoj5353-村通网【最小生成树】

正题 题目大意 一条边的价格为两个点的曼哈顿距离乘B&#xff0c;修建源点价格为A。要求每个联通块内都有源点的最小价格。 解题思路 对于最终每个联通块肯定是棵树。对于合并每个联通块可以减少一个源点。所以将最小生成树上价格小于A的边都加进去就可以了。 codecodecode …

auto.js小案例

微信朋友圈自动点赞 var it className("ListView").findOne(); var i1;while(i<5){say desc(评论).findOne();say.click();goodtext(赞).findOne();goodpgood.parent();goodp.click();sleep(1000);it.scrollDown();i; }home();微信轰炸机 toast("轰炸机已准…

本土开源、立足全球 | COSCon'17

全球公有云 90% 的服务器运行的是开源 Linux 操作系统&#xff01; GitHub 上有超过 150 万个组织&#xff0c;正在进行开源开发&#xff01; 本土开源项目目前在 Apache 的顶级以及孵化列表中已经有 6 个&#xff01; 你想知道这其中都有什么奥秘吗&#xff1f;Apache 顶级项目…

Zookeeper选举原理——FastLeaderElection

转载自 Zookeeper选举原理 作为一个分布式应用程序协调服务&#xff0c;在大型网站中&#xff0c;其本身也是集群部署的&#xff0c;安装zookeeper的时候最好是单数节点&#xff0c;因为要选举。Zookeeper的leader节点是集群工作的核心&#xff0c;用来更新并保证leader和ser…

P2742-二维凸包/圈奶牛Fencing the Cows【凸包】

正题 题目链接:https://www.luogu.org/recordnew/lists?uidSSL_WYC_zombieeeeee&pidP2742&status&sort0 题目大意 求凸包总长度 解题思路 求凸包 codecodecode #include<cstdio> #include<algorithm> #include<cmath> #define N 10010 usin…

Wamp升级php到7.3版本

在网上找了关于cms的模板&#xff0c;结果显示php版本低于7.2的无法使用。 找了很多wamp和xampp的安装包&#xff0c;要不然版本没到7.2&#xff0c;要不然安装无法使用&#xff0c;浪费了很多时间 于是想自己手动把php升到7.3版本&#xff0c;刚开始看教程&#xff0c;特别麻烦…