javascript中原型链(__proto__)与原型(prototype)
JavaScript中原型链(proto)与原型(prototype)
在JavaScript中,理解原型链(__proto__)和原型(prototype)对于深入掌握面向对象编程至关重要。本文将通过示例代码,详细解析__proto__和prototype之间的关系,以及它们在对象和构造函数之间的作用。
一、基本概念
1. 构造函数与实例对象
- 构造函数:在JavaScript中,函数可以作为构造函数使用,通过
new关键字创建实例对象。 - 实例对象:由构造函数创建的对象,继承了构造函数的属性和方法。
2. 原型(prototype)
- prototype:每个函数(包括构造函数)都有一个
prototype属性,指向一个对象,这个对象被称为原型对象。 - 原型对象:存储共享的属性和方法,供所有实例对象访问。
3. 原型链(__proto__)
- proto:每个对象都有一个
__proto__属性,指向创建该对象的构造函数的原型对象。 - 原型链:通过
__proto__属性,将对象、构造函数和原型对象连接起来,形成一个链式结构。
二、示例代码解析
下面通过一段示例代码,逐步解析__proto__和prototype之间的关系。
function Person(name, age){this.name = name;this.age = age;
}const person = new Person('Tom', 18);// 构造函数的prototype就是实例对象的__proto__
console.log(Person.prototype === person.__proto__); // true// 实例对象的constructor指向构造函数
console.log(person.constructor === Person); // true// 实例对象的__proto__对象上的constructor指向的又是Person构造函数
console.log(person.__proto__.constructor === Person); // true// 实例对象的__proto__对象的__proto__指向的是Object构造函数的prototype
console.log(person.__proto__.__proto__ === Object.prototype); // true// 每一个构造函数也是一个对象,所以也都有__proto__属性,指向的是Function构造函数的prototype
console.log(Person.__proto__ === Function.prototype); // true// Function构造函数的prototype的constructor指向Function构造函数
console.log(Function.prototype.constructor === Function); // true// Function的prototype的__proto__指向Object的prototype
console.log(Function.prototype.__proto__ === Object.prototype); // true// 因为所有构造函数的__proto__都是指向Function的prototype,所以Function构造函数的prototype和__proto__是相等的
console.log(Function.__proto__ === Function.prototype); // true
1. 实例对象与构造函数的关系
console.log(Person.prototype === person.__proto__); // true
- 解析:
Person.prototype是构造函数Person的原型对象。person.__proto__是实例对象person的原型,指向Person.prototype。- 因此,
Person.prototype === person.__proto__返回true。
2. 实例对象的constructor属性
console.log(person.constructor === Person); // true
- 解析:
- 实例对象
person的constructor属性指向其构造函数Person。 - 因此,
person.constructor === Person返回true。
- 实例对象
3. 原型对象的constructor属性
console.log(person.__proto__.constructor === Person); // true
- 解析:
person.__proto__是Person.prototype,它有一个constructor属性,指向构造函数Person。- 因此,
person.__proto__.constructor === Person返回true。
4. 原型链向上查找
console.log(person.__proto__.__proto__ === Object.prototype); // true
- 解析:
person.__proto__是Person.prototype。Person.prototype.__proto__指向Object.prototype。- 因此,
person.__proto__.__proto__ === Object.prototype返回true。
5. 构造函数也是对象
console.log(Person.__proto__ === Function.prototype); // true
- 解析:
- 构造函数
Person本身是一个函数对象,所以它的__proto__属性指向Function.prototype。 - 因此,
Person.__proto__ === Function.prototype返回true。
- 构造函数
6. Function构造函数的关系
console.log(Function.prototype.constructor === Function); // true
console.log(Function.prototype.__proto__ === Object.prototype); // true
console.log(Function.__proto__ === Function.prototype); // true
- 解析:
Function.prototype是Function构造函数的原型对象。Function.prototype.constructor指向Function自身。Function.prototype.__proto__指向Object.prototype,因为函数也是对象。Function.__proto__指向Function.prototype,因为Function也是函数,是自己的构造函数。- 因此,上述三个
console.log均返回true。
三、原型链查找属性的过程
console.log(person.__proto__); // Person {}
console.log(person.__proto__.__proto__); // Object {}
console.log(person.__proto__.__proto__.__proto__); // null
- 解析:
person.__proto__是Person.prototype。person.__proto__.__proto__是Object.prototype。person.__proto__.__proto__.__proto__为null,表示原型链的顶端。
四、总结
1. 关于__proto__和prototype
-
__proto__:- 是每个对象都有的内置属性,指向其构造函数的原型对象。
- 用于实现对象的原型链,在查找属性时,如果对象自身没有,会沿着
__proto__向上查找。
-
prototype:- 是构造函数的属性,指向原型对象。
- 原型对象上定义的方法和属性会被构造函数的所有实例共享。
2. 关于构造函数和实例对象
-
实例对象的
__proto__:- 指向构造函数的
prototype属性。
- 指向构造函数的
-
实例对象的
constructor:- 通过
__proto__找到原型对象,原型对象的constructor指向构造函数。
- 通过
-
构造函数的
__proto__:- 因为构造函数本身是一个函数对象,所以它的
__proto__指向Function.prototype。
- 因为构造函数本身是一个函数对象,所以它的
3. 关于原型链的查找过程
- 当访问对象的属性时,JavaScript引擎会先查找对象自身的属性。
- 如果找不到,会沿着
__proto__属性指向的原型对象继续查找。 - 这个过程会一直持续,直到找到属性或到达原型链的顶端(
null)。
4. 关于Function和Object
-
Function构造函数:
- 是所有函数的构造函数,包括
Function自身。 Function.__proto__ === Function.prototype,因为Function是一个函数,其__proto__指向Function.prototype。
- 是所有函数的构造函数,包括
-
Object构造函数:
- 是所有对象的构造函数,包括
Function.prototype。 Function.prototype.__proto__ === Object.prototype。
- 是所有对象的构造函数,包括
五、深入思考
-
为什么
Function.__proto__ === Function.prototype?- 因为
Function是所有函数的构造函数,包括它自己。Function作为一个函数对象,其__proto__指向Function.prototype。
- 因为
-
为什么
Object.__proto__ === Function.prototype?Object是一个函数(构造函数),所以其__proto__指向Function.prototype。
-
为什么
Function.prototype.__proto__ === Object.prototype?Function.prototype是一个对象,因此其__proto__指向Object.prototype。
相关文章:
javascript中原型链(__proto__)与原型(prototype)
JavaScript中原型链(proto)与原型(prototype) 在JavaScript中,理解原型链(__proto__)和原型(prototype)对于深入掌握面向对象编程至关重要。本文将通过示例代码,详细解析__proto__和prototype之间的关系&a…...
基于多种机器学习的酒店客户流失预测模型的研究与实现
文章目录 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主项目介绍实现过程 有需要本项目的代码或文档以及全部资源,或者部署调试可以私信博主 项目介绍 项目背景: 在当今竞争激烈的酒店行业中,预测和防止客户流…...
Unity实现自定义图集(三)
以下内容是根据Unity 2020.1.0f1版本进行编写的 1、实现编辑器模式下进游戏前Pack全部自定义图集 同Unity的图集一样,Unity的编辑器模式会在进游戏前把全部的SpriteAtlas都打一次图集,如图: 我们也实现这样的效果。 首先需要获取全部的图集路径。因为目前使用的是以.…...
【测开面试真题】
针对地图导航设计测试用例 文章目录 1. selenium 定位元素的方式有几种?2. 自动化测试能够取代人工测试吗?3. 什么是回归测试? 1. selenium 定位元素的方式有几种? 🐧①通过CSS选择器定位;🐧②…...
RelationGraph实现工单进度图——js技能提升
直接上图: 从上图中可以看到整个工单的进度是从【开始】指向【PCB判责】【完善客诉】【PCBA列表】,同时【完善客诉】又可以同时指向【PCB判责】【PCBA列表】,后续各自指向自己的进度。 直接上代码: 1.安装 1.1 Npm 方式 npm …...
针对脚本爬虫攻击的防御策略与实现
随着互联网的发展,网站和应用程序面临着越来越多的自动化攻击,其中包括使用脚本进行的大规模数据抓取,即所谓的“爬虫攻击”。这类攻击不仅影响网站性能,还可能导致敏感数据泄露。本文将探讨如何识别爬虫攻击,并提供一…...
JVM发展历程
JVM发展历程 Sun Classic VM 早在1996年Java1.0版本的时候,Sun公司发布了一款名为sun classic VM的Java虚拟机,它同时也是世界上第一款商用Java虚拟机,JDK1.4时完全被淘汰。这款虚拟机内部只提供解释器。现在还有及时编译器,因此…...
C语言 | Leetcode C语言题解之第470题用Rand7()实现Rand10()
题目: 题解: // The rand7() API is already defined for you. // int rand7(); // return a random integer in the range 1 to 7int rand10() {while(true) {int index (rand7() - 1) * 7 rand7(); if(index < 40) return index % 10 1; } }...
【JavaScript】拷贝对象的几种方式与对比
#工作中拷贝对象是常有的事,我们需要分清楚深浅拷贝,一般来说要做的都是深拷贝,不然会有关联影响# 解构赋值 es6新语法,简洁是简洁,但是需要注意深拷贝只针对第一层 使用方式:{...obj} let stu {name:…...
高防服务器为何有时难以防御CC攻击及其对策
高防服务器通常被用来抵御各种类型的DDoS攻击,包括CC(Challenge Collapsar)攻击。然而,在某些情况下,即使是配备了高级防护措施的高防服务器也可能难以完全防御CC攻击。本文将探讨导致这一现象的原因,并提供…...
性能测试工具locust —— Python脚本参数化!
1.1.登录用户参数化 在测试过程中,经常会涉及到需要用不同的用户登录操作,可以采用队列的方式,对登录的用户进行参数化。如果数据要保证不重复,则取完不再放回;如可以重复,则取出后再返回队列。 def lo…...
Java中的拦截器、过滤器及监听器
过滤器(Filter)监听器(Listener)拦截器(Interceptor)关注点web请求系统级别参数、对象Action(部分web请求)如何实现函数回调事件Java反射机制(动态代理)应用场…...
Nginx 和 Lua 设计黑白名单
使用 Nginx 和 Lua 设计黑白名单机制,借助 Redis 存储 在现代网络应用中,安全性是一个不可忽视的关键因素。应用程序需要能够有效地管理访问权限,以保护其资源不被恶意用户攻击。黑白名单机制是实现访问控制的一种有效方式。本文将详细介绍如…...
【部署篇】Redis-01介绍
一、Redis介绍 1、什么是Redis? Redis,英文全称是Remote Dictionary Server(远程字典服务),Redis是一个开源的、使用ANSI C语言编写的Key-Value存储系统,支持网络、可基于内存亦可持久化。 它提…...
R语言的Meta分析【全流程、不确定性分析】方法与Meta机器学习技术应用
Meta分析是针对某一科研问题,根据明确的搜索策略、选择筛选文献标准、采用严格的评价方法,对来源不同的研究成果进行收集、合并及定量统计分析的方法,最早出现于“循证医学”,现已广泛应用于农林生态,资源环境等方面。…...
【text2sql】ReFSQL检索生成框架
论文标题为《ReFSQL: A Retrieval-Augmentation Framework for Text-to-SQL Generation》,发表在 EMNLP 2023 上。ReFSQL框架通过结构增强检索器来获取与当前问题语义和模式结构相似的样本,然后通过对比学习机制来引导模型学习到这些样本的特定知识&…...
美国市场跨平台应用程序本地化流程的特点
为美国市场本地化移动应用程序是为了创造一种自然、直观、与多元化和精通技术的受众文化相关的体验。美国是世界上最大、最具竞争力的应用程序市场之一,用户期望高质量的性能以及在个人层面引起共鸣的内容。这个市场的本地化需要对美国语言、文化和行为有细致入微的…...
STM32 实现 TCP 服务器与多个设备通信
目录 一、引言 二、硬件准备 三、软件准备 四、LWIP 协议栈的配置与初始化 五、创建 TCP 服务器 1.创建 TCP 控制块 2.绑定端口 3. 进入监听状态 4.设置接收回调函数 六、处理多个客户端连接 七、数据处理与通信管理 八、错误处理与资源管理 九、总结 一、引…...
EdgeNAT: 高效边缘检测的 Transformer
EdgeNAT: Transformer for Efficient Edge Detection 介绍了一种名为EdgeNAT的基于Transformer的边缘检测方法。 1. 背景与动机 EdgeNAT预测结果示例。(a, b):来自BSDS500的数据集的输入图像。(c, d):对应的真实标签。(e, f):由EdgeNAT检测到的边缘。(e)显示了由于颜色变化…...
Github优质项目推荐 - 第六期
文章目录 Github优质项目推荐 - 第六期一、【WiFiAnalyzer】,3.4k stars - WiFi 网络分析工具二、【penpot】,33k stars - UI 设计与原型制作平台三、【Inpaint-Anything】,6.4k stars - 修复图像、视频和3D 场景中的任何内容四、【Malware-P…...
未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?
编辑:陈萍萍的公主一点人工一点智能 未来机器人的大脑:如何用神经网络模拟器实现更智能的决策?RWM通过双自回归机制有效解决了复合误差、部分可观测性和随机动力学等关键挑战,在不依赖领域特定归纳偏见的条件下实现了卓越的预测准…...
React 第五十五节 Router 中 useAsyncError的使用详解
前言 useAsyncError 是 React Router v6.4 引入的一个钩子,用于处理异步操作(如数据加载)中的错误。下面我将详细解释其用途并提供代码示例。 一、useAsyncError 用途 处理异步错误:捕获在 loader 或 action 中发生的异步错误替…...
OpenLayers 可视化之热力图
注:当前使用的是 ol 5.3.0 版本,天地图使用的key请到天地图官网申请,并替换为自己的key 热力图(Heatmap)又叫热点图,是一种通过特殊高亮显示事物密度分布、变化趋势的数据可视化技术。采用颜色的深浅来显示…...
【入坑系列】TiDB 强制索引在不同库下不生效问题
文章目录 背景SQL 优化情况线上SQL运行情况分析怀疑1:执行计划绑定问题?尝试:SHOW WARNINGS 查看警告探索 TiDB 的 USE_INDEX 写法Hint 不生效问题排查解决参考背景 项目中使用 TiDB 数据库,并对 SQL 进行优化了,添加了强制索引。 UAT 环境已经生效,但 PROD 环境强制索…...
【快手拥抱开源】通过快手团队开源的 KwaiCoder-AutoThink-preview 解锁大语言模型的潜力
引言: 在人工智能快速发展的浪潮中,快手Kwaipilot团队推出的 KwaiCoder-AutoThink-preview 具有里程碑意义——这是首个公开的AutoThink大语言模型(LLM)。该模型代表着该领域的重大突破,通过独特方式融合思考与非思考…...
如何在看板中有效管理突发紧急任务
在看板中有效管理突发紧急任务需要:设立专门的紧急任务通道、重新调整任务优先级、保持适度的WIP(Work-in-Progress)弹性、优化任务处理流程、提高团队应对突发情况的敏捷性。其中,设立专门的紧急任务通道尤为重要,这能…...
uniapp中使用aixos 报错
问题: 在uniapp中使用aixos,运行后报如下错误: AxiosError: There is no suitable adapter to dispatch the request since : - adapter xhr is not supported by the environment - adapter http is not available in the build 解决方案&…...
视频行为标注工具BehaviLabel(源码+使用介绍+Windows.Exe版本)
前言: 最近在做行为检测相关的模型,用的是时空图卷积网络(STGCN),但原有kinetic-400数据集数据质量较低,需要进行细粒度的标注,同时粗略搜了下已有开源工具基本都集中于图像分割这块,…...
视觉slam十四讲实践部分记录——ch2、ch3
ch2 一、使用g++编译.cpp为可执行文件并运行(P30) g++ helloSLAM.cpp ./a.out运行 二、使用cmake编译 mkdir build cd build cmake .. makeCMakeCache.txt 文件仍然指向旧的目录。这表明在源代码目录中可能还存在旧的 CMakeCache.txt 文件,或者在构建过程中仍然引用了旧的路…...
云原生安全实战:API网关Kong的鉴权与限流详解
🔥「炎码工坊」技术弹药已装填! 点击关注 → 解锁工业级干货【工具实测|项目避坑|源码燃烧指南】 一、基础概念 1. API网关(API Gateway) API网关是微服务架构中的核心组件,负责统一管理所有API的流量入口。它像一座…...
