原型链prototype、__proto、constructor的那些问题整理

再了解原型链之前,我们先来看看构造函数和实例对象的打印结构

- 函数

这里我们定义一个构造函数Fn,然后打印它的结构吧

function Fn(){}
console.dir(Fn)

控制台得到结构
在这里插入图片描述
从上面结构我们能看的出来,函数有两种原型,一种是作为函数特有的原型:prototype,另一种是作为对象的__proto__类型(就是上图那个[[Prototype]],__proto__是浏览器自己填充的,新浏览器都能看到,我的浏览器版本低,还看不到哈,先这么写)

我们先来看做为函数特有属性的prototype哈,我们展开看看
在这里插入图片描述
可以看到函数的prototype上有一个构造函数constructor和一个__proto__属性,这个constructor实际上就是函数本身,另外一个__proto__呢,你看它的值是一个对象Object呢.也就是说函数的prototype的__proto__指向Object的prototype,我们下面运行看看是不是这样呢?

Fn.prototype.__proto__ === Object.prototype.    // true

我们运行结果果然和预期一样返回了true.

我们再来看函数的另外一个原型__proto__,我们展开它

在这里插入图片描述
我们看到函数的__proto__是一个Function,我们猜想这个函数的__proto__指向Function的prototype,我们来运行看看

Fn.proto === Function.prototype. // true

果然,和预期一样,所以我们根据上面的一些结果有了总结

1、函数有两个原型,一个是作为函数特有的prototype,另一个是作为对象的__proto__
2、函数的 prototype中constructor就是函数本身
3、函数的 prototype中__proto__属性指向Object的prototype
4、函数的__proto__指向Function的prototype

  • 对象

现在我们根据上面的构造函数,我们实例化一个对象来看看结构

let obj = new Fn()
console.dir(obj)

我们来看看obj对象的结构

在这里插入图片描述
可以看到上面的obj对象只有一个__proto__原型,我们展开看似乎和它的构造函数的prototype长的一样呢,我们运行看看

obj.proto === Fn.prototype. // true

果然,结果和我们预期一样

所以我们有了结论:

对象只有一条__proto__原型,并且对象的原型__proto__就指向构造函数的prototype

  • constrctor

我们再回过头来看刚刚构造函数中那个constrctor,上面你看实例对象obj可以找到构造函数的prototype,而这个prototype上就有constrctor,所以由此得出根据构造函数实例得到的每一个实例对象,都能找到它的构造函数

我们来运行看看哈

 obj.__proto__.constructor    // ƒ Fn(){}

没有问题,和预期一样,这么看,我们现在就可以把上面写法精简一下,因为对象上的属性和方法,自己上面没有,就会去它的原型链上面去找,也就是对象会有原型的继承

根据这个原则,我们把上面运行的就能精简一下了

obj.constructor.   //. ƒ Fn(){}

我们就这样就找到了构造函数了.

这里找到构造函数的目的是啥呢,除了用它来实例化对象之外,还能给原型链添加公共的属性和方法,供所有的实例对象调用.

我们来看一段代码

obj.constructor.prototype.sayHello = function(){ console.log("hello")}
obj.sayHello().  // hello
let obj2 = new obj.constructor()
obj2.sayHello(). // hello

从上得出,我们可以通过constructor的prototype添加通用的属性和方法.

有人提出干嘛那么麻烦,我们通过对象的__proto__直接添加属性和方法不是更好嘛,代码更精简,我们来看看

obj.proto.name = “zhang”
obj.name. // “zhang”
obj.name // “zhang”

我们看到我们通过对象的__proto__也能添加构造函数的公用属性和方法,所以,这样写到底有没有问题呢?

其实这样写虽然在浏览器运行没有问题,但是上面我们提到过,__proto__这个属性是浏览器厂商自己内置的,有的浏览器是不支持的,所以使用constructor更可靠一点。

就先整理到这里

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

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

相关文章

Java设计模式 _结构型模式_适配器模式

一、适配器模式 **1、适配器模式(Adapter Pattern)**是一种结构型设计模式。适配器类用来作为两个不兼容的接口之间的桥梁,使得原本不兼容而不能一起工作的那些类可以一起工作。譬如:读卡器就是内存卡和笔记本之间的适配器。您将…

这样狠心的女人,不配当妈!

男人小时候经常受父亲虐待,初中毕业就到深圳打拼,基本与父母再无联系。 因为心有创伤,他没有考虑过结婚的事情,也不希望自己的娃成为受苦的一代。 然而,机缘巧合,他偶然之间认识了自己的爱人。 在妻子小的时…

意法半导体STM32F407VET6TR单片机优缺点、参数、应用和引脚封装

ST(意法半导体)的型号STM32F407VET6TR属于32位MCU微控制器,基于高性能的ArmCortex-M4 32位RISC核心,工作频率高达168MHz。单精度浮点单元(FPU)用于Cortex-M4核心,支持所有Arm单精度数据处理指令和数据类型。它还实现了一套完整的DSP指令和一个…

printjs打印表格的时候多页的时候第一页出现空白

现象:打印多页的时候第一页空白了,一页的时候没有问题 插件:printjs 网上搜索半天找到的方式解决: 1. 对于我这次的现象毫无作用。其他情况不得而知,未遇见过。(这个应该是大家用的比较多的方式&#xf…

[SpringBoot] JWT令牌——登录校验

JWT(JSON Web Token)是一种用于在网络应用之间传递信息的开放标准(RFC 7519)。它由三部分组成:头部(header)、载荷(payload)和签名(signature)。J…

Mybatis-plus 字段结果为NULL

问题 Mybatis-plus 字段结果为NULL 详细问题 笔者使用SpringBootMybatis-plus 进行项目开发。进行接口请求测试,在确定SQL语句没有问题的前提下,返回记录部分字段(譬如字段name)为空。 解决方案 修改Mybatis-plus中mapper的xml文件,使re…

JavaEE初阶——多线程(七)——定时器

T04BF 👋专栏: 算法|JAVA|MySQL|C语言 🫵 小比特 大梦想 此篇文章与大家分享多线程的第七篇文章——关于定时器 如果有不足的或者错误的请您指出! 目录 4.定时器4.1标准库提供的定时器4.2自己实现一个定时器4.2.1任务类4.2.2Timer类4.2.3 有一个线程来负…

如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题

🐯 如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题 🐾 文章目录 🐯 如何解决IntelliJ IDEA 2024打开项目时频繁闪退问题 🐾摘要引言正文📘 识别问题📙 内存配置调整步骤1: 定位vmoptions文件步骤2: 修改…

svg图标填充渐变色及CSS鼠标悬停纯色渐变色转换

svg图标填充渐变色及CSS鼠标悬停纯色渐变色转换&#xff1a; HTML&#xff1a; <!--底部导航--> <ul class"milliaNav"> <li class"active"><a href"#"> <svg class"icon" viewBox"0 0 1024 1024&qu…

1分钟掌握 Python 函数参数

任何编程语言函数都是非常重要的一部分&#xff0c;而在进行函数调用时&#xff0c;了解函数的参数传递方式是非常有必要的。Python中支持哪些传参方式呢&#xff1f; Python中的传参方式是比较灵活的&#xff0c;主要包括以下六种&#xff1a; 按照位置传参按照关键字传参默…

力扣--N皇后

题目: 按照国际象棋的规则&#xff0c;皇后可以攻击与之处在同一行或同一列或同一斜线上的棋子。 n 皇后问题 研究的是如何将 n 个皇后放置在 nn 的棋盘上&#xff0c;并且使皇后彼此之间不能相互攻击。 给你一个整数 n &#xff0c;返回所有不同的 n 皇后问题 的解决方案。…

李彦宏:程序员将不复存在! 周鸿祎回怼!网友:先把百度程序员都开除了!

近日&#xff0c;百度创始人、董事长兼首席执行官李彦宏在央视《对话》•开年说的访谈中指出&#xff1a;“基本上说以后其实不会存在“程序员”这种职业了&#xff0c;因为只要会说话&#xff0c;人人都会具备程序员的能力”。 “未来的编程语言只会剩下两种&#xff0c;一种…

Java进阶-异常处理

概述 常见运行时异常 直接继承自RuntimeException或者子类&#xff0c;编译阶段不会报错&#xff0c;运行时可能出现的错误 运行时异常&#xff1a;一般是程序员业务没有考虑好或者是编程逻辑不严谨引起的程序错误 数组索引越界异常空指针异常类型转换异常数学操作异常数字转…

离线语音模块初步学习——LSYT201B(深圳雷龙发展)

一 、产品简介 首先简单介绍下该离线语音模块&#xff0c;官方给出的介绍是&#xff1a;YT2228 是根据智能语音交互市场需求及思必驰算法的发展方向定义开发的 “芯片算法”人工智能人机语音交互解决方案&#xff0c;具有高性能、低功耗等特点。该芯片通过软硬融合的方法&…

数据丢失的谜团:文件突然不见了,却还占用着空间

在数字化时代&#xff0c;数据的重要性不言而喻。然而&#xff0c;有时我们会遇到一个令人困惑的问题&#xff1a;明明存储在设备中的文件突然不见了&#xff0c;但磁盘空间仍被占用。这种情况究竟是怎么回事&#xff1f;我们又该如何找回这些“消失”的文件呢&#xff1f;接下…

ROS python实现乌龟跟随

产生两只乌龟&#xff0c;中间的乌龟(A) 和 左下乌龟(B), B 会自动运行至A的位置&#xff0c;并且键盘控制时&#xff0c;只是控制 A 的运动&#xff0c;但是 B 可以跟随 A 运行 乌龟跟随实现的核心&#xff0c;是乌龟A和B都要发布相对世界坐标系的坐标信息&#xff0c;然后&am…

力扣HOT100 - 994. 腐烂的橘子

解题思路&#xff1a; 因为要记录轮数&#xff08;分钟数&#xff09;&#xff0c;所以不能一口气遍历到底&#xff0c;所以不能用深搜&#xff08;bfs&#xff09;&#xff0c;而要用广搜&#xff08;bfs&#xff0c;层序遍历&#xff09;。 先记录下新鲜橘子数&#xff0c;…

理解控制反转

好久之前写的学习笔记&#xff0c;一直落在草稿箱里今天才发现&#xff0c;既然写了就补发出来吧~ 当需要实现不同操作时&#xff0c;用户和程序员都无需修改&#xff0c;只需要修改xml配置即可。 代码体现&#xff1a; 不同接口的实现类&#xff1a; xml具体配置 通过set注入…

GO语言写Prometheus自定义node-exporter的Docker容器测试

1. 安装docker-compose 执行以下命令&#xff0c;安装docker-compose到CentOS7.9环境中&#xff1a; # 下载二进制文件 sudo curl -L "https://github.com/docker/compose/releases/download/v2.24.7/docker-compose-$(uname -s)-$(uname -m)" -o /usr/local/bin/d…

Qt : 在QTreeWidget中添加自定义右键菜单

一、引言 如图&#xff0c;我们需要在一个QTreeWidget 控件中添加了自定义右键菜单。 二、思路 如何做到的呢&#xff0c;很简单。浅浅记录和分享一下。 继承QTreeWidget&#xff0c;定义一个子类CustomTreeWidget &#xff0c;在重写contextMenuEvent 事件即可。 三、代…