如何理解原型及原型链?js的继承方式
原型与原型链
- 原型
在js中,每个对象都有一个原型(prototype)。原型是一个对象,其他对象可以通过原型来共享属性和方法。当我们创建一个对象时,它会自动关联到一个原型对象。
例如:
在上面的代码中,创建了一个Person对象,有通过person创建了person1和person2对象,这两个对象都关联到function Person(name, age) { this.name = name; this.age = age; }// 在 Person 构造函数的原型上添加一个 greet 方法 Person.prototype.greet = function() { console.log(`Hello, my name is ${this.name}.`); };const person1 = new Person('Alice', 30); const person2 = new Person('Bob', 25);person1.greet(); // 输出 "Hello, my name is Alice." person2.greet(); // 输出 "Hello, my name is Bob."
Person.prototype
原型对象,并且可以共享greet
方法。 - 原型链
原型链是福哦个对象通过原型链条连接在一起的数据结构。当访问一个对象的属性或方法时,js引擎会先在对象本身中寻找,如果找不到,就会沿着原型链继续找,知道找到该属性或方法,或者达到原型链的顶端(Object.prototype
)。
举个例子:
function Person(name, age) {this.name = name;this.age = age;
}Person.prototype.greet = function() {console.log(`Hello, my name is ${this.name}.`);
};const person1 = new Person('Alice', 30);console.log(person1.toString()); // 输出 "[object Object]"
在这个例子中 person1通过原型链继承了toString方法。
所以是Object.prototype
原型链的顶端,它是所有对象的原型,包括内置对象和自定义对象。当查找属性或方法时,原型链会一直往上查找,直到 Object.prototype
。如果在整个原型链上都找不到该属性或方法,则返回 undefined
。
原型链继承
原型继承是通过原型链来实现对象间的属性和方法共享。在原型继承中,一个对象可以从另一个对象继承属性和方法,这样可以实现对象之间的复用和扩展。
原型继承的基本概念如下:
- 每个 JavaScript 对象都有一个原型对象(prototype),它是一个普通对象。
- 当访问一个对象的属性或方法时,如果该对象本身没有该属性或方法,JavaScript 引擎会沿着原型链向上查找,直到找到为止。
- 原型链是由多个对象通过原型关联形成的链条,最终的原型对象通常是
Object.prototype
,它是 JavaScript 中所有对象的原型。 - 如果在整个原型链上都找不到该属性或方法,则返回
undefined
。
在原型继承中,我们可以通过构造函数的原型对象来共享属性和方法。当使用 new
关键字调用构造函数创建对象时,新对象会关联到该构造函数的原型,从而继承原型上的属性和方法。
下面是一个使用原型继承的简单示例:
// 定义一个 Person 构造函数
function Person(name) {this.name = name;
}// 在 Person 的原型上添加一个 greet 方法
Person.prototype.greet = function() {console.log(`Hello, my name is ${this.name}.`);
};// 使用 Person 构造函数创建两个对象
const person1 = new Person('Alice');
const person2 = new Person('Bob');// 调用对象的 greet 方法
person1.greet(); // 输出 "Hello, my name is Alice."
person2.greet(); // 输出 "Hello, my name is Bob."
在上面的代码中,Person
构造函数的原型对象上有一个 greet
方法,通过 new Person()
创建的对象(例如 person1
和 person2
)会共享这个方法。这样,我们可以通过原型继承在多个对象之间共享方法,提高代码的重用性和可维护性。
需要注意的是,原型继承只能继承原型上的属性和方法,而不能继承构造函数内部的局部变量。如果需要更灵活的继承方式,可以考虑其他方式,例如组合继承、原型式继承、寄生式继承等。
js的其他继承方式
- 组合继承
组合继承时结合了原型链继承和构造函数继承的一种继承方式。他通过在给子类的构造函数中调用父类的构造函数来继承父类的属性,并通过将子类的原型指向一个新的创建的父类对象来继承的方法。
function Parent(name) {this.name = name;
}Parent.prototype.greet = function() {console.log(`Hello, my name is ${this.name}.`);
};function Child(name, age) {Parent.call(this, name); // 构造函数继承this.age = age;
}Child.prototype = Object.create(Parent.prototype); // 原型链继承
Child.prototype.constructor = Child;const child = new Child('Alice', 5);
child.greet(); // 输出 "Hello, my name is Alice."
- 寄生式继承
寄生式继承是在原型式的基础上增强新对象,添加额外的属性和方法。
function createPerson(proto, age) {const newPerson = createObject(proto); // 原型式继承newPerson.age = age; // 增强对象newPerson.introduce = function() {console.log(`I am ${this.name} and I am ${this.age} years old.`);};return newPerson;
}const person = {name: 'Alice',greet: function() {console.log(`Hello, my name is ${this.name}.`);}
};const newPerson = createPerson(person, 30);
newPerson.greet(); // 输出 "Hello, my name is Alice."
newPerson.introduce(); // 输出 "I am Alice and I am 30 years old."
- 寄生组合式继承
寄生组合式继承是对组合继承的一种优化,通过构造函数继承属性,同时利用Object.create()方法来继承原型,避免了调用父类构造函数时产生的不必要的属性重复赋值问题。
function Parent(name) {this.name = name;
}Parent.prototype.greet = function() {console.log(`Hello, my name is ${this.name}.`);
};function Child(name, age) {Parent.call(this, name); // 构造函数继承this.age = age;
}Child.prototype = Object.create(Parent.prototype); // 原型链继承
Child.prototype.constructor = Child;const child = new Child('Alice', 5);
child.greet(); // 输出 "Hello, my name is Alice."
- 构造函数式继承
function Animal(name) {this.name = name;
}function Dog(name, breed) {Animal.call(this, name);this.breed = breed;
}const dog = new Dog('Buddy', 'Golden Retriever');
console.log(dog.name); // 输出 "Buddy"
相关文章:
如何理解原型及原型链?js的继承方式
原型与原型链 原型 在js中,每个对象都有一个原型(prototype)。原型是一个对象,其他对象可以通过原型来共享属性和方法。当我们创建一个对象时,它会自动关联到一个原型对象。 例如:function Person(name, a…...
C# 按表格中的某列排序/查询
using System; using System.Data; using System.Linq;class Program {static void Main(){// 创建一个示例的 DataTable 对象DataTable table new DataTable();table.Columns.Add("ID", typeof(int));table.Columns.Add("Name", typeof(string));table.R…...
【Vue】】img使用 :src 动态绑定图片地址,但是加载图片不成功
问题复现: img标签直接动态绑定图片的相对路径的时候,图片不能正常显示。代码如下所示 <view style"margin: 20rpx" v-for"(item, index) in showSampleImage" :key"index"><u-image :src"item.src"…...

list模拟
之前模拟了string,vector,再到现在的list,list的迭代器封装最让我影响深刻。本次模拟的list是双向带头节点的循环链表,该结构虽然看起来比较复杂,但是却非常有利于我们做删除节点的操作,结构图如下。 由于其节点结构特…...

python字典:怎么取出key对应的值
目录 python中的字典是什么 怎么判断key是否在字典中 怎么取出key对应的值 总结 python中的字典是什么 在Python中,字典(Dictionary)是一种无序且可变的数据类型,用于存储键-值(Key-Value)对。字典通过…...

okvis
论文 Keyframe-Based Visual-Inertial SLAM Using Nonlinear Optimization 摘要 由于两种感知模式的互补性,视觉和惯性线索的融合在机器人中变得很流行。虽然迄今为止大多数融合策略都依赖于过滤方案,但视觉机器人界最近转向了非线性优化方法&#x…...
fabric js双击弹出菜单, 双击弹出输入框 修改文字 群组对象
<!DOCTYPE html> <html lang"en"> <head><meta charset"UTF-8"><title>测试1</title><style type"text/css">body {background-color: #ccc;float: left;}#main {background-color: #fff;border: 1px…...

路由器工作原理
路由器原理 路由概述 路由:跨越从源主机到目标主机的一个互联网络来转发数据包的过程。(为数据包选择路径的过程) 作用:路由器是连接不同网段的。 转发依据: 路由表:路径选择全看路由表,根…...

在centos 7系统docker上构建mysql 5.7
一、VM上已经安装centos 7.9,且已完成docker的构建 二、安装mysql5.7 安装镜像:[rootlocalhost lll]# docker pull mysql:5.7 查看镜像[rootlocalhost lll]# docker images 根据镜像id构建mysql容器,且分配端口号[rootlocalhost lll]# dock…...

数据库的介绍和分类
目录 一、数据库的介绍和分类 二、命令行客户端 三、数据操作 四、查询的基本操作 五、条件查询 六、分组和聚合 资料获取方法 一、数据库的介绍和分类 数据库:长期存储在计算机内、有组织的数据集合 数据库的分类: 关系型数据库 以表格的形式…...
职责链模式——请求的链式处理
1、简介 1.1、概述 很多情况下,在一个软件系统中可以处理某个请求的对象不止一个。例如SCM系统中的采购单审批,主任、副董事长、董事长和董事会都可以处理采购单,他们可以构成一条处理采购单的链式结构。采购单沿着这条链进行传递ÿ…...

docker中涉及的挂载点总结
文章目录 1.场景描述2. 容器信息在主机上位置3. 通过docker run 命令4、通过Dockerfile创建挂载点5、容器共享卷(挂载点)6、最佳实践:数据容器 1.场景描述 在介绍VOLUME指令之前,我们来看下如下场景需求: 1ÿ…...

elasticsearch 官方优化建议
.一般建议 a.不要返回过大的结果集。这个建议对一般数据库都是适用的,如果要获取大量结果,可以使用search_after api,或者scroll (新版本中已经不推荐)。 b.避免大的文档。 2. 如何提高索引速度 a.使用批量请求。为了…...
Kubernetes(K8s)从入门到精通系列之五:K8s的基本概念和术语之应用类
Kubernetes K8s从入门到精通系列之五:K8s的基本概念和术语之应用类 一、Service与Pod二、Label与标签选择器三、Pod与Deployment四、Service的ClusterIP地址五、Service的外网访问问题六、有状态的应用集群七、批处理应用八、应用配置问题九、应用的运维一、Service与Pod Ser…...

DevOps(四)
CD(二) 1. CDStep 1 - 上传代码Step 2 - 下载代码Step 3 - 检查代码Step 4 - 编译代码Step 5 - 上传仓库Step 6 - 下载软件Step 7 - 制作镜像Step 8 - 上传镜像Step 9 - 部署服务2. 整体预览2.1 预览1. 修改代码2. 查看sonarqube检查结果3. 查看nexus仓库4. 查看harbor仓库5.…...

Element-plus侧边栏踩坑
问题描述 el-menu直接嵌套el-menu-item菜单,折叠时不会出现文字显示和小箭头无法隐藏的问题,但是实际开发需求中难免需要把el-menu-item封装为组件 解决 vue3项目中嵌套两层template <template><template v-for"item in list" :k…...

支持多种通信方式和协议方便接入第三方服务器或云平台
2路RS485串口是一种常用的通信接口,可以支持Modbus Slave协议,并可接入SCADA、HMI、DSC、PLC等上位机。它还支持Modbus RTU Master协议,可用于扩展多达48个Modbus Slave设备,如Modbus RTU远程数据采集模块、电表、水表、柴油发电机…...

使用 OpenCV 进行图像模糊度检测(拉普拉斯方差方法)
写在前面 工作中遇到,简单整理人脸识别中,对于模糊程度较高的图像数据,识别率低,错误率高。虽然使用 AdaFace 模型,对低质量人脸表现尤为突出。但是还是需要对 模糊程度高的图像进行丢弃处理当前通过阈值分类ÿ…...

神经网络简单介绍
人工神经网络(artififial neural network) 简称神经网络,它是一种模仿生物神经网络结构和功能的非线性数学模型。 神经网络通过输入层接受原始特征信息,再通过隐藏层进行特征信息的加工和提取,最后通过输出层输出结果。 根据需要神经网络可以…...

16位S912ZVML32F3MKH、S912ZVML31F1WKF、S912ZVML31F1MKH混合信号MCU,适用于汽车和工业电机控制应用。
S12 MagniV微控制器是易于使用且高度集成的混合信号MCU,非常适合用于汽车和工业应用。S12 MagniV MCU提供单芯片解决方案,是基于成熟的S12技术的完整系统级封装 (SiP) 解决方案,在整个产品组合内软件和工具都兼容。 S12 MagniV系统级封装 (S…...
应用升级/灾备测试时使用guarantee 闪回点迅速回退
1.场景 应用要升级,当升级失败时,数据库回退到升级前. 要测试系统,测试完成后,数据库要回退到测试前。 相对于RMAN恢复需要很长时间, 数据库闪回只需要几分钟。 2.技术实现 数据库设置 2个db_recovery参数 创建guarantee闪回点,不需要开启数据库闪回。…...

SCAU期末笔记 - 数据分析与数据挖掘题库解析
这门怎么题库答案不全啊日 来简单学一下子来 一、选择题(可多选) 将原始数据进行集成、变换、维度规约、数值规约是在以下哪个步骤的任务?(C) A. 频繁模式挖掘 B.分类和预测 C.数据预处理 D.数据流挖掘 A. 频繁模式挖掘:专注于发现数据中…...
【android bluetooth 框架分析 04】【bt-framework 层详解 1】【BluetoothProperties介绍】
1. BluetoothProperties介绍 libsysprop/srcs/android/sysprop/BluetoothProperties.sysprop BluetoothProperties.sysprop 是 Android AOSP 中的一种 系统属性定义文件(System Property Definition File),用于声明和管理 Bluetooth 模块相…...
拉力测试cuda pytorch 把 4070显卡拉满
import torch import timedef stress_test_gpu(matrix_size16384, duration300):"""对GPU进行压力测试,通过持续的矩阵乘法来最大化GPU利用率参数:matrix_size: 矩阵维度大小,增大可提高计算复杂度duration: 测试持续时间(秒&…...

QT: `long long` 类型转换为 `QString` 2025.6.5
在 Qt 中,将 long long 类型转换为 QString 可以通过以下两种常用方法实现: 方法 1:使用 QString::number() 直接调用 QString 的静态方法 number(),将数值转换为字符串: long long value 1234567890123456789LL; …...
MySQL用户和授权
开放MySQL白名单 可以通过iptables-save命令确认对应客户端ip是否可以访问MySQL服务: test: # iptables-save | grep 3306 -A mp_srv_whitelist -s 172.16.14.102/32 -p tcp -m tcp --dport 3306 -j ACCEPT -A mp_srv_whitelist -s 172.16.4.16/32 -p tcp -m tcp -…...
QT3D学习笔记——圆台、圆锥
类名作用Qt3DWindow3D渲染窗口容器QEntity场景中的实体(对象或容器)QCamera控制观察视角QPointLight点光源QConeMesh圆锥几何网格QTransform控制实体的位置/旋转/缩放QPhongMaterialPhong光照材质(定义颜色、反光等)QFirstPersonC…...

FFmpeg:Windows系统小白安装及其使用
一、安装 1.访问官网 Download FFmpeg 2.点击版本目录 3.选择版本点击安装 注意这里选择的是【release buids】,注意左上角标题 例如我安装在目录 F:\FFmpeg 4.解压 5.添加环境变量 把你解压后的bin目录(即exe所在文件夹)加入系统变量…...

springboot 日志类切面,接口成功记录日志,失败不记录
springboot 日志类切面,接口成功记录日志,失败不记录 自定义一个注解方法 import java.lang.annotation.ElementType; import java.lang.annotation.Retention; import java.lang.annotation.RetentionPolicy; import java.lang.annotation.Target;/***…...
用鸿蒙HarmonyOS5实现中国象棋小游戏的过程
下面是一个基于鸿蒙OS (HarmonyOS) 的中国象棋小游戏的实现代码。这个实现使用Java语言和鸿蒙的Ability框架。 1. 项目结构 /src/main/java/com/example/chinesechess/├── MainAbilitySlice.java // 主界面逻辑├── ChessView.java // 游戏视图和逻辑├──…...