js原型、原型链和继承
文章目录
- 一、原型
- 1、prototype
- 2、constructor
- 二、原型链
- 1、字面量原型链
- 2、字面量继承
- 3、构造函数的原型链
- 4、Object.create
- 5、Object.setPrototypeOf
- 三、继承
- 1、构造函数继承
- 2、原型链继承
- 3、组合继承
- 四、常见链条
- 1、Function
- 2、Object.prototype
继承是指将特性从父代传递给子代,以便新代码可以重用并基于现有代码的特性进行构建。JavaScript 使用对象实现继承。每个对象都有一条链接到另一个称作原型的对象的内部链。该原型对象有自己的原型,依此类推,直到原型是 null 的对象。
一、原型
1、prototype
- 构造函数自带原型对象
prototype
,可以在prototype增加属性和方法,这样构造函数产生的实例可以共享这些属性和方法(如果实例上没有的话)- 实例
__proto__
属性指向最近的上级prototype(如果有继承),如果没有继承那么指向构造函数的prototype;__proto__在浏览器上显示的是[[Prototype]]
- 注意原型对象prototype也是对象,他是被Object创建出来的
const ParentFun = function () {this.name = "张三";
};
ParentFun.prototype.getName = function () {return this.name;
};
const parentObj = new ParentFun();
parentObj.__proto__ === ParentFun.prototype // true
2、constructor
constructor
其实依赖于prototype,只是prototype上的一个属性,指向构造函数本身(函数对象,函数也可以被认为是一个对象,可以挂载属性和方法)- 在原型链继承的时候,错误操作可能只顾着继承prototype,而丢失constructor属性
instanceof
: a instanceof b会在链条往上查找prototype.constructor,看a的原型链上有没有b;逐级上查
const ParentFun = function () {this.name = "张三";
};
ParentFun.prototype.constructor === ParentFun // true
// 等同于;因为ParentFunObj默认往上查找一层就是ParentFun.prototype
ParentFunObj.constructor === ParentFun // trueconst ParentFunObj = new ParentFun();
ParentFunObj instanceof ParentFun // true
ParentFunObj instanceof Object // true
二、原型链
1、字面量原型链
- 注意对象中设置字面量{ proto: … },是被允许的、合理的;不合理是设置隐式原型obj.proto = …
const obj = {a: 1,// __proto__ 设置了 [[Prototype]]。在这里它被指定为另一个对象字面量。__proto__: {b: 2,__proto__: {c: 3,},},
};
obj.a // 1
obj.b // 2
obj.c // 3
2、字面量继承
const parent = {value: 2,method() {return this.value + 1;}
};// child 是一个继承了 parent 的对象
const child = {__proto__: parent
};console.log(child.method()); // 3// child ---> parent ---> Object.prototype ---> null
3、构造函数的原型链
function Constructor() {}const obj = new Constructor();// obj ---> Constructor.prototype ---> Object.prototype ---> null
4、Object.create
const a = { a: 1 };
// a ---> Object.prototype ---> nullconst b = Object.create(a);
// b ---> a ---> Object.prototype ---> null
console.log(b.a); // 1(继承的)
5、Object.setPrototypeOf
const obj = { a: 1 };
const anotherObj = { b: 2 };
Object.setPrototypeOf(obj, anotherObj);
// obj ---> anotherObj ---> Object.prototype ---> null
三、继承
1、构造函数继承
- call、apply都可以
- 也可以使用class,本文案例未举例
const ParentFun = function () {this.name = "张三";
};
const ChildFun = function () {// 继承父类的属性和方法;构造函数继承;// 注意调用的时机,会决定实例的属性顺序;比如这里的name属性在age前面ParentFun.call(this);// 运行时this指向childFunc实例对象(的内存空间);this.age = 20;
};
2、原型链继承
Object.setPrototypeOf(ChildFun.prototype, ParentFun.prototype)
:给目标设置原型链的上一级;Object.setPrototypeOf(ChildFun.prototype)
:获取该目标的原型链的上一级Object.create(ParentFun.prototype)
:创建和返回新对象,设置该对象的原型链上一级- 原型链扩充,每次扩充都会形成上级和下级的二元链;链条可以被设置成连续不断一直到顶层null,也可以设置成短链
const ParentFun = function () {this.name = "张三";
};
const ChildFun = function () {// 继承父类的属性和方法;构造函数继承;// 注意调用的时机,会决定实例的属性顺序;比如这里的name属性在age前面ParentFun.call(this);// 运行时this指向childFunc实例对象(的内存空间);this.age = 20;
};
ParentFun.prototype.getName = function () {return this.name;
};
ChildFun.prototype.getAge = function () {return this.age;
};const transferTemp = (Parent, Child) => {// 空的对象作为临时原型链;const Temp = () => {};Temp.prototype = Parent.prototype;Child.prototype = new Temp();Child.prototype.constructor = Child;
};const transferCreat = (Parent, Child) => {// Object.create本身就会返回一个空对象,该对象的__proto__指向Parent.prototype;Child.prototype = Object.create(Parent.prototype);// 覆盖prototype以后会丢失constructor,需要重新赋值;// constructor在一些判断中可能被用到// prototype在此之前设置的其他属性也会消失(比如getAge)Child.prototype.constructor = Child;
};// 注意原型链继承方式的区别
// 1
// ChildFun.prototype = new ParentFun();
// 2 废弃但可用;__proto__ 赋值只会接受对象,其他值会被忽略
// ChildFun.prototype.__proto__ = ParentFun.prototype;
// 3 推荐 安全有效,没有中转对象
// Object.setPrototypeOf(ChildFun.prototype, ParentFun.prototype);
// 4 使用中转对象
// transferTemp(ParentFun, ChildFun);
// 5 使用中转对象
// transferCreat(ParentFun, ChildFun);
3、组合继承
const ParentFun = function () {this.name = "张三";
};
const ChildFun = function () {// 继承父类的属性和方法;构造函数继承;// 注意调用的时机,会决定实例的属性顺序;比如这里的name属性在age前面ParentFun.call(this);// 运行时this指向childFunc实例对象(的内存空间);this.age = 20;
};
ParentFun.prototype.getName = function () {return this.name;
};
ChildFun.prototype.getAge = function () {return this.age;
};// 自定义Object.keys方法 用于获取对象所有属性名
Object.prototype.keysCustom = function (obj) {if (typeof obj !== "object" || obj === null) {return;}const result = []; // 用于存储结果for (let key in obj) {// hasOwnProperty表示自身的属性,不包括原型链上的属性if (obj.hasOwnProperty(key)) {// 相当于循环后存储keyresult.push(key);}}return result;
};Object.setPrototypeOf(ChildFun.prototype, ParentFun.prototype);const childObj = new ChildFun();const keysAll = [];
const keysOwn = [];
for (let key in childObj) {// 自己的属性和原型链上的属性都会遍历出来;// 原型链继承的所有属性 + Object.prototype 挂载的自定义方法keysAll.push(key);if (childObj.hasOwnProperty(key)) {// 自己的属性才会遍历出来;keysOwn.push(key);}
}
// console.log("Object.keysCustom", keysAll, keysOwn, childObj); // TEST
// 结果:keysAll = ["name", "age", "getName", "keysCustom"];
// 结果: keysOwn = ["name", "age"];// childObj ---> ChildFun.prototype ---> ParentFun.prototype ---> Object.prototype ---> null
四、常见链条
1、Function
- Function是所有常见构造函数的源头,甚至他自己也被自己创造
- 只要是构造函数都归Function管理,包括自定义的函数
// Function创造自己
Object.getPrototypeOf(Function) === Function.prototype // true
// 常规构造函数
Object.getPrototypeOf(Object) === Function.prototype // true
Object.getPrototypeOf(Array) === Function.prototype // true
// 自定义构造函数
const temp =() => {}
Object.getPrototypeOf(temp) === Function.prototype // true
2、Object.prototype
- 只要是对象都归Object管理,包括prototype对象,当然有例外:Object.prototype
// 常规构造函数的prototype;上一级就是Object.prototype
Object.getPrototypeOf(Function.prototype) === Object.prototype // true
Object.getPrototypeOf(Array.prototype) === Object.prototype // true
// 链条顶层被null强制了
Object.getPrototypeOf(Object.prototype) === Object.prototype // false
Object.getPrototypeOf(Object.prototype) === null // true
相关文章:
js原型、原型链和继承
文章目录 一、原型1、prototype2、constructor 二、原型链1、字面量原型链2、字面量继承3、构造函数的原型链4、Object.create5、Object.setPrototypeOf 三、继承1、构造函数继承2、原型链继承3、组合继承 四、常见链条1、Function2、Object.prototype 继承是指将特性从父代传递…...
看不见的彼方:交换空间——小菜一碟
有个蓝色的链接,先去看看两年前的题目的write up (https://github.com/USTC-Hackergame/hackergame2022-writeups/blob/master/official/%E7%9C%8B%E4%B8%8D%E8%A7%81%E7%9A%84%E5%BD%BC%E6%96%B9/README.md) 从别人的write up中了解到&…...
传奇996_38——称号系统
记住: 称号是装备,加属性的 特效是顶戴,加特效的 需要两个命令分开设置,称号和特效不关联 角色-称号栏显示的图标:由装备表字段,背包显示Looks控制,图片位置在:stab\res\private\t…...
C++:异常
---什么是异常? 异常是面向对象语法处理错误的一种方式。 ---C语言传统的处理错误的方式有哪些呢? 1.返回错误码,有些API接口都是把错误码放到errno中。 2.终止程序,比如发生越界等严重问题时,我们也可以主动调用exit…...
winScp连接Ubantu系统,访问拒绝的解决方式
一、原理分析 win10系统能够通过WinScp连接到Ubantu系统的前提是Ubantu系统开启ssh服务 二、解决步骤 1、Ubantu系统开启ssh服务 更新软件列表 sudo apt update安装OpenSSH服务器 sudo apt install openssh-server开启SSH服务 service sshd start到此,winScp…...
Oracle 建表的存储过程
建表的存储过程 下面是建表的存储过程,用途:通过不同的表,根据不同过滤条件,得到某个字段,例如neid,然后创建一个新表T,表T的表名为拼接XXXX_XXX_neid,表T的字段自行添加 xxx&…...
芯科科技率先支持Matter 1.4,推动智能家居迈向新高度
Matter 1.4引入核心增强功能、支持新设备类型,持续推进智能家居互联互通 近日,连接标准联盟(Connectivity Standard Alliance,CSA)发布了Matter 1.4标准版本。作为连接标准联盟的重要成员之一,以及Matter标…...
pandas快速解决空列表问题
在使用 Pandas 处理数据时,我们经常会遇到包含空列表(即空值或缺失值)的问题。Pandas 提供了一些非常有效的方法来处理这些空列表,使得数据清理和预处理变得更加简单和高效。 以下是一个示例,展示如何使用 Pandas 快速…...
sentinel使用手册
1.引入依赖 <dependency><groupId>com.alibaba.cloud</groupId><artifactId>spring-cloud-starter-alibaba-sentinel</artifactId></dependency>2.yaml spring:cloud:sentinel:transport:dashboard: localhost:8090 #sentinel控制台地址…...
【继承】—— 我与C++的不解之缘(十九)
前言: 面向对象编程语言的三大特性:封装、继承和多态 本篇博客来学习C中的继承,加油! 一、什么是继承? 继承(inheritance)机制是⾯向对象程序设计使代码可以复⽤的最重要的⼿段,它允许我们在保持原有类…...
腾讯微众银行大数据面试题(包含数据分析/挖掘方向)面试题及参考答案
为什么喜欢使用 XGBoost,XGBoost 的主要优势有哪些? XGBoost 是一个优化的分布式梯度增强库,在数据科学和机器学习领域应用广泛,深受喜爱,原因主要在于其众多突出优势。 首先,它的精度高,在许多机器学习竞赛和实际应用中,XGBoost 都展现出卓越的预测准确性。其基于决策…...
组合数练习题——c++
题目设置: 现在有x个相同的小球,分给y个人,每个人至少分k个,请问有多少种可能的分发方法,由于结果可能较大,答案对10^97取模。 输入格式: 一行3个整数:x,y, k…...
Java:JPMS模块化开发
JPMS(Java Platform Module System)简介 为什么用JPMS? JPMS(Java 平台模块系统)是 Java 9 引入的模块化系统,也称为 Jigsaw 项目。它为 Java 提供了更精细的模块化机制,用于组织和管理代码&a…...
Spring Boot中配置Flink的资源管理
在 Spring Boot 中配置 Flink 的资源管理,需要遵循以下步骤: 添加 Flink 依赖项 在你的 pom.xml 文件中,添加 Flink 和 Flink-connector-kafka 的依赖项。这里以 Flink 1.14 版本为例: <!-- Flink dependencies --><de…...
【ruby on rails】dup、deep_dup、clone的区别
一、区别 dup 浅复制:dup 方法创建对象的浅复制。 不复制冻结状态:dup 不会复制对象的冻结状态。 不复制单例方法:dup 不会复制对象的单例方法。 deep_dup 深复制:deep_dup 方法创建对象的深复制,递归复制嵌套的对象。…...
鸿蒙开发-HMS Kit能力集(应用内支付、推送服务)
1 应用内支付 开发步骤 步骤一:判断当前登录的华为账号所在服务地是否支持应用内支付 在使用应用内支付之前,您的应用需要向IAP Kit发送queryEnvironmentStatus请求,以此判断用户当前登录的华为帐号所在的服务地是否在IAP Kit支持结算的国…...
springboot中使用mongodb完成评论功能
pom文件中引入 <!-- mongodb --> <dependency><groupId>org.springframework.boot</groupId><artifactId>spring-boot-starter-data-mongodb</artifactId> </dependency> yml中配置连接 data:mongodb:uri: mongodb://admin:1234561…...
南京仁品耳鼻喉专科医院:12月启动公益义诊月
专业医疗资源送至“家门口”!南京仁品耳鼻喉专科医院启动公益义诊月 随着2024年即将步入尾声,南京仁品耳鼻喉医院为回馈社会,提升公众健康福祉,将于12月隆重推出“三甲专家公益义诊月”活动。此次活动旨在通过汇聚众多耳鼻喉领域…...
微信小程序首页搜索框的实现教程
微信小程序首页搜索框的实现教程 前言 在现代移动应用中,搜索功能是用户获取信息的主要方式之一。对于购物小程序而言,提供一个美观且高效的搜索框,可以显著提升用户体验,帮助用户快速找到他们想要的商品。本文将详细介绍如何在微信小程序中实现一个样式优美的搜索框,包…...
Educational Codeforces Round 151 (Rated for Div. 2)
题目链接 B. Come Together 题意 输入 输出 思路 可以将B、C坐标作A的变换,将A平移至原点,然后分情况讨论: B、C两点都在轴上,具体分为同向轴和其他情况B、C两点都在象限中,具体分为相同象限、对角象限和相邻象限分别位于象限…...
第二十一天 深度学习简介
深度学习(Deep Learning,简称DL)是机器学习的一个分支,它通过构建和训练深层神经网络模型,从数据中学习和提取特征,以实现复杂任务的自动化处理和决策。以下是对深度学习的详细介绍: 一、起源与…...
mongodb/redis/neo4j 如何自己打造一个 web 数据库可视化客户端?
随笔 从千万粉丝“何同学”抄袭开源项目说起,为何纯技术死路一条? 数据源的统一与拆分 监控报警系统的指标、规则与执行闭环 我们的系统应该配置哪些监控报警项? 监控报警系统如何实现自监控? java 老矣,尚能饭否ÿ…...
elementUI如何dialog对话框 不设置 点击遮罩层 自动关闭的功能
背景 用户在填写dialog对话框的时候,有时候误触 遮罩层,导致form表单直接关闭,用户的信息丢失 代码 要使对话框在点击遮罩层时关闭,您需要在 el-dialog 组件上将 close-on-click-modal 属性设置为 false。以下是更新后的代码&…...
循环神经网络:从基础到应用的深度解析
🍛循环神经网络(RNN)概述 循环神经网络(Recurrent Neural Network, RNN)是一种能够处理时序数据或序列数据的深度学习模型。不同于传统的前馈神经网络,RNN具有内存单元,能够捕捉序列中前后信息…...
LeetCode 100.相同的树
题目: 给你两棵二叉树的根节点 p 和 q ,编写一个函数来检验这两棵树是否相同。 如果两个树在结构上相同,并且节点具有相同的值,则认为它们是相同的。 思路:灵神 代码: class Solution {public boolean…...
序列化与反序列化
序列化是将对象转换为可被存储或传输的格式,例如将对象转换为字节流或字符串。序列化的过程可以将对象的状态保存下来,以便在需要时可以重新创建对象。 反序列化则是将序列化的对象转换回原始的对象形式,以便可以使用和操作这些对象。 序列…...
spring boot打包fat jar
所谓fat jar就是包含所有依赖的jar以及其他开发的代码的jar包。可以通过java -jar xxx.jar直接启动运行,不需要部署到tomcat中间件就能运行。 接下来我们使用maven进行打包: (1)在需要带包的主模块的pom中添加build依赖…...
2021年美亚杯电子数据取证大赛-个人赛
资格赛-案件背景 2021年10月某日早上,本市一个名为"大路建设"的高速公路工地主管发现办公室的计算机被加密并无法开启,其后收到了勒索通知。考虑到高速公路的基建安全,主管决定报警。警方调查人员到达现场取证,发现办公…...
用 React 编写一个笔记应用程序
这篇文章会教大家用 React 编写一个笔记应用程序。用户可以创建、编辑、和切换 Markdown 笔记。 1. nanoid nanoid 是一个轻量级和安全的唯一字符串ID生成器,常用于JavaScript环境中生成随机、唯一的字符串ID,如数据库主键、会话ID、文件名等场景。 …...
泛型擦除是什么?
泛型擦除(Type Erasure)是Java编译器在编译泛型代码时的一种机制,它的目的是确保泛型能够与JAVA的旧版本(即不支持泛型的版本)兼容。泛型擦除会在编译时移除泛型类型信息,并将泛型类型替换为其非泛型的上限类型(通常是Object) 详细解释 在Java中&#…...
鸿蒙Next星河版基础代码
目录: 1、鸿蒙箭头函数的写法2、鸿蒙数据类型的定义3、枚举的定义以及使用4、position绝对定位及层级zIndex5、字符串的拼接转换以及数据的处理(1)字符串转数字(2)数字转字符串(3)布尔值转换情况(4)数组的增删改查 6、三元表达式7、鸿蒙for循环的几种写法7.1、基本用…...
物联网智能项目:智能家居系统的设计与实现
物联网(Internet of Things,IoT)技术正在迅速改变我们的生活方式,特别是在智能家居、工业自动化、环境监控等领域。物联网智能项目通过将设备、传感器、控制器等通过互联网连接,实现设备间的智能交互,带来高效、便捷和智能的体验。本文将介绍一个典型的物联网智能家居项目…...
STL算法之set相关算法
STL一共提供了四种与set(集合)相关的算法,分别是并集(union)、交集(intersection)、差集(difference)、对称差集(symmetric difference)。 目录 set_union set_itersection set_difference set_symmetric_difference 所谓set,可细分为数学上定义的和…...
STM32主要功能
STM32 是由意法半导体(STMicroelectronics)推出的一系列基于 ARM Cortex-M 内核的微控制器(MCU)。STM32 微控制器广泛应用于嵌入式系统中,因其高性能、低功耗、丰富的外设接口和多种封装形式而被广泛采用。其主要功能和…...
【数据结构】--ArrayList与顺序表
文章目录 1. 线性表2. 顺序表3. ArrayList简介4. MyArrayList的实现5. ArrayList使用5.1 ArrayList的构造5.2 ArrayList常见操作5.3 ArrayList的遍历5.4 ArrayList的扩容机制 6. ArrayList的具体使用6.1 简单的洗牌算法6.2 杨辉三角 1. 线性表 线性表(linear list&…...
多线程篇-3--java内存模型(主内存,共享内存,三大特性,指定重排)
Java内存模型 Java Memory Model,简称JMM,本身是一种抽象的概念,实际上并不存在,它描述的是一组规范,通过这组规范定义了程序中各个变量(包括实例字段,静态字段和构成数组对象的元素࿰…...
Android Studio的AI工具插件使用介绍
Android Studio的AI工具插件使用介绍 一、前言 Android Studio 的 AI 工具插件具有诸多重要作用,以下是一些常见的方面: 代码生成与自动补全 代码优化与重构 代码解读 学习与知识获取 智能搜索与资源推荐实际使用中可以添加注释,解读某段代…...
【Yarn Bug】 yarn 安装依赖出现的网络连接问题
最近,在初始化 Ant Design Pro 前端脚手架过程中,使用 yarn 安装依赖时遇到了网络连接问题,具体错误信息提示为 info There appears to be trouble with your network connection. Retrying...。通过百度查询,得知出现这种问题的原…...
Vue3的Setup语法动态获取Dom或调用子组件方法
官方文档:https://cn.vuejs.org/api/composition-api-setup.html#composition-api-setup 获取Dom <template><div class"todo" ref"todoDom" click"handleClick"></div> </template><script lang"t…...
中科院一区算法KO-K均值优化算法(K-means Optimizer)-附Matlab免费代码
首先,使用K-means算法在每次迭代中建立聚类区域的形心向量,然后KO提出两种移动策略,以在开发和探索能力之间建立平衡。每次迭代中探索或开发的移动策略的决定取决于一个参数,该参数将被设计为识别每个搜索代理是否在访问的区域中过…...
python数据可视化销量柱状图练习
需求: 假设某店铺的商品销量分为 线上销量 和 线下销量: 使用 叠加柱状图 分别显示线上和线下销量。 在柱状图中添加每种商品的总销量。 图表美观,包含图例、网格、颜色区分等。 代码实现: import matplotlib.pyplot as plt imp…...
甘特图全面指南:原理、制作与实际案例
甘特图(Gantt Chart)是一种用于项目管理的直观工具,以条形图的形式展示任务的时间进度和依赖关系。它通过简单明了的视觉效果帮助团队跟踪任务进展,分配资源并优化时间安排。本文将深入介绍甘特图的定义、制作方法,以及…...
如何创建 MySQL 数据库的副本 ?
MySQL 是一个广泛使用的开源数据库系统,它提供了多种数据库复制的方法。此功能对于确保跨不同环境的数据可用性和完整性至关重要。 管理 MySQL 数据库通常需要创建数据库的副本。这个任务被称为 MySQL 数据库复制,对于备份、测试、服务器迁移和其他关键…...
基于YOLO模型的目标检测与识别实现在ESP32-S3 EYE上全流程部署
前言 文章首发于 基于YOLO模型的目标检测与识别实现在ESP32-S3 EYE上全流程部署 文章目录 前言项目环境安装ESP-IDF安装开发环境运行环境 训练数据集准备添加自定义数据集 下载预训练模型训练 YOLO 模型模型量化和格式转换模型结果评估训练损失评估指标模型推理 模型部署部署环…...
2411C++,CXImage简单使用
介绍 CxImage是一个可非常简单快速的加载,保存,显示和转换图像的C类. 文件格式和链接的C库 Cximage对象基本上是加了一些成员变量来保存有用信息的一个位图: class CxImage{...protected:void* pDib; //包含标题,调色板,像素BITMAPINFOHEADER head; //标准头文件CXIMAGEINFO…...
Java对象与XML互相转换(xstream)
依赖 <dependency><groupId>com.thoughtworks.xstream</groupId><artifactId>xstream</artifactId><version>1.4.18</version></dependency> 实体类 package com.itheima.util;import lombok.AllArgsConstructor; import lom…...
计算机视觉工程师紧张学习中!
在当今这个日新月异的科技时代,计算机视觉作为人工智能的重要分支,正以前所未有的速度改变着我们的生活和工作方式。为了紧跟时代步伐,提升自我技能,一群怀揣梦想与热情的计算机视觉设计开发工程师们聚集在了本次线下培训活动中。…...
网关整合sentinel无法读取nacos配置问题分析
sentinel无法读取nacos配置问题分析 1.spring-cloud-gateway整合sentinel2.问题现象3.原因猜测4.源码分析4. 结语 最近公司需要上线一个集约项目,虽然为内网项目,但曾经有过内网被攻破,导致内部系统被攻击的案例,且集约系统同时在…...
速盾:高防 CDN 中高级缓存有什么用?
在高防 CDN(Content Delivery Network,内容分发网络)的服务体系里,高级缓存功能犹如一颗强大的 “性能优化引擎”,对于提升网站或应用的运行效率、减轻源站压力以及改善用户体验等诸多方面都发挥着极为关键的作用。 一…...
大数据期末笔记
第一章、大数据概述 人类的行为及产生的事件的一种记录称之为数据。 1、大数据时代的特征,并结合生活实例谈谈带来的影响。 (一)特征 1、Volume 规模性:数据量大。 2、Velocity高速性:处理速度快。数据的生成和响…...