JavaScript 中的 Class 类


文章目录
- 🔥 引言
- 🎯 基础知识
- 🏗️ 构造函数 (Constructor)
- 🔐 私有字段 (Private Fields)
- 🔐 私有方法 (Private Methods)
- 🧬 继承 (Inheritance)
- 📦 静态方法与属性 (Static Methods and Properties)
- 静态方法
- 静态属性
- 示例代码
- 🔄 Getter 和 Setter 解析
- 基本概念
- 示例代码分析
- 重要用途
- 注意事项
- 📚 总结
- 🔐 相关链接
🔥 引言
在ECMAScript 2015(ES6)中,
class关键字被引入,为JavaScript带来了一种更接近传统面向对象语言的语法糖。类是创建对象的模板,它们封装了数据(属性)和行为(方法),是实现面向对象编程的基础单元。🎈
🎯 基础知识
在JavaScript这门灵活多变的语言中,Class是ES6引入的一个重要特性,它为面向对象编程提供了一种更简洁、更清晰的语法糖。通过Class,我们可以更容易地创建对象和管理继承关系。本文将从基础到进阶,带你深入探索Class的世界,让代码更加优雅且易于理解。👩🏫
基本声明
Class关键字用于定义一个类。类是一种蓝图,用于创建具有特定属性和方法的对象。
class Person {constructor(name, age) {this.name = name;this.age = age;}sayHello() {console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);}
}
constructor是类的构造函数,用于初始化新创建的实例。sayHello是类的一个方法。
创建实例
创建类的实例就像调用构造函数一样简单:
const alice = new Person('Alice', 30);
alice.sayHello(); // 输出: Hello, my name is Alice and I am 30 years old.
🏗️ 构造函数 (Constructor)
构造函数是一个特殊的方法,用于初始化新创建的对象。每当你使用 new 关键字创建类的实例时,构造函数会被自动调用。
// 定义一个Person类,包含姓名(name)和年龄(age)属性
class Person {/*** 构造函数* @param {string} name - 人的名字* @param {number} age - 人的年龄*/constructor(name, age) {// 使用'this'关键字给实例绑定属性// 'this'在此处指的是新创建的Person实例this.name = name; // 绑定name属性this.age = age; // 绑定age属性}
}// 使用'new'关键字创建Person类的实例
const alice = new Person('Alice', 30);// 访问alice实例的name属性,输出:Alice
console.log(alice.name); // 输出: Alice
- 构造函数签名:构造函数的名称必须是
constructor,且没有返回值类型声明。 - 参数:构造函数可以接收任意数量的参数,这些参数用于初始化实例的属性。
- this的使用:在构造函数内部,
this是一个特殊的关键字,它指向新创建的实例对象。 - 默认值与验证:虽然本例未展示,但在构造函数中可以加入逻辑来为参数设置默认值或进行有效性验证。
- 自动调用:实例化时,构造函数自动执行,无需手动调用
🔐 私有字段 (Private Fields)
ES2022 引入了私有字段的概念,通过在字段名前加 # 符号来声明,确保了字段的私密性和安全性。
class User {// 声明一个私有字段 #password#password;/*** 构造函数,用于初始化User实例* @param {string} password - 用户的密码*/constructor(password) {// 使用私有字段 #password 存储密码this.#password = password;}/*** 公共方法,安全地获取密码(实际应用中应谨慎处理密码)* @returns {string} 返回存储的密码*/getPassword() {return this.#password;}
}// 创建User类的实例
const user = new User('mySecret');// 通过公共方法访问私有字段
console.log(user.getPassword()); // 输出: mySecret// 尝试直接访问私有字段会导致语法错误
// console.log(user.#password); // 这里会引发错误,因为#password是私有的
- 封装性增强:私有字段有效限制了对类内部状态的直接访问,促进了良好的封装实践。
- 安全性提升:防止外部代码无意或恶意修改类的内部数据,减少潜在的bug。
- 设计原则:鼓励使用公共方法(getter/setter)来控制对私有字段的访问,便于未来修改内部实现而不影响外部接口。
- 语法提示:编辑器和IDE通常会根据井号标记来提示哪些字段是私有的,帮助开发者遵循最佳实践。
虽然私有字段提高了封装性,但在设计API时,应谨慎考虑哪些数据应该设为私有,以平衡封装与灵活性的需求。
🔐 私有方法 (Private Methods)
私有方法是ES2020引入的另一项关键特性,与私有字段类似,它们通过在方法名前添加#符号来定义,以此增强类的封装性并保护类的内部实现细节不被外部访问或篡改。
class Calculator {// 声明一个私有方法 #multiply#multiply(a, b) {// 实现乘法逻辑return a * b;}/*** 公共方法,计算两个数的乘积* @param {number} a - 第一个乘数* @param {number} b - 第二个乘数* @returns {number} 两数的乘积*/calculateProduct(a, b) {// 内部可以无障碍访问私有方法 #multiplyreturn this.#multiply(a, b);}
}// 创建Calculator类的实例
const calc = new Calculator();// 通过公共方法间接调用私有方法,得到正确结果
console.log(calc.calculateProduct(2, 3)); // 输出: 6// 尝试直接访问或调用私有方法会导致语法错误
// console.log(calc.#multiply(2, 3)); // 这是不允许的,会导致编译或运行时错误
- 封装性:私有方法隐藏了类的内部计算逻辑,只暴露必要的公共接口,符合面向对象设计的封装原则。
- 安全性:防止外部代码直接调用或修改私有方法,减少潜在错误和安全风险。
- 设计模式:鼓励使用面向接口而非实现编程,增强代码的灵活性和可测试性。
- 代码提示:现代IDE能够识别出私有方法,给予开发者明确的视觉提示,减少误操作。
私有方法是JavaScript类中一种强大的工具,它帮助开发者构建更加健壮、安全和易于维护的代码库。正确使用私有方法,是提升代码质量和团队协作效率的关键之一。
🧬 继承 (Inheritance)
JavaScript中的类支持继承,使用 extends 关键字来实现。子类可以继承父类的属性和方法,并可覆盖或扩展它们。
class Animal { // 父类或基类constructor(name) {this.name = name; // 初始化属性}// 定义一个方法speak() {console.log(`${this.name} makes a noise.`);}
}class Dog extends Animal { // 子类或派生类,使用extends继承Animalconstructor(name) {super(name); // 调用父类构造函数,传递参数}// 重写父类的speak方法以适应Dog类的特性speak() {console.log(`${this.name} barks.`);}
}const myDog = new Dog('Rex'); // 创建Dog类的实例
myDog.speak(); // 输出: Rex barks.
extends关键字:用于创建一个类作为另一个类的子类,继承其所有非私有属性和方法。super关键字:在子类构造函数中调用,用于访问父类的构造函数。这对于正确初始化继承自父类的属性至关重要。- 方法重写:子类可以定义与父类同名的方法,从而实现方法的覆盖(重写),根据子类的特点定制功能。
- 访问控制与继承:父类的公有和受保护成员(没有使用
#声明的)可以被子类继承和访问,私有成员则不能直接访问。 - 多级继承:JavaScript支持多级继承,即一个子类可以再被其他类继承,形成继承链。
高级议题
- Mixins与多重继承替代方案:由于JavaScript不直接支持多重继承,开发者可以利用组合、 Mixins模式或使用类的静态方法来模拟多重继承的效果。
- 抽象类与接口概念:虽然JavaScript原生不支持抽象类和接口,但可以通过设计模式和约定来模仿这些概念,指导类的设计与实现。
通过继承机制,JavaScript的类体系能够构建层次清晰、复用性强的代码结构,是面向对象编程中不可或缺的一部分。
📦 静态方法与属性 (Static Methods and Properties)
静态方法和属性是类的一部分,它们不依赖于类的实例,可以直接通过类名访问。这使得静态成员成为执行与类的实例无关操作的理想选择,比如工具函数或常量值。在JavaScript中,使用static关键字来定义静态成员。
静态方法
- 定义:静态方法是与类关联而非与类的实例关联的方法。它们通常用于执行与类的实例无关的操作,比如实用函数。
- 访问:通过类名直接调用,无须创建类的实例。
- 示例:在
MathUtil类中,add是一个静态方法,用于执行简单的加法运算,不依赖于任何特定实例的状态。
静态属性
- 定义:静态属性是类级别的变量,所有类的实例共享同一份数据。它们通常用于存储类的常量值或配置信息。
- 初始化:静态属性可以在类定义中直接赋值,或者使用类的静态初始化块(ES2022引入)进行更复杂的初始化逻辑。
- 示例:
PI是一个静态属性,存储圆周率的近似值,对所有MathUtil的调用者都是一致的。
示例代码
class MathUtil {// 静态属性定义,存储π的值static PI = 3.14159;// 静态方法定义,实现两个数的相加static add(a, b) {return a + b;}
}// 直接通过类名调用静态方法和属性
console.log(MathUtil.add(2, 3)); // 输出: 5
console.log(MathUtil.PI); // 输出: 3.14159// 注意:静态成员不能通过类的实例访问
// const util = new MathUtil();
// util.add(2, 3); // 这是不推荐的,尽管技术上可行,但违反了静态方法的使用原则
- 共享性:静态方法和属性对于类的所有实例都是共享的,修改它们会影响所有实例。
- 内存占用:每个静态成员只占用一份内存空间,不同于实例成员每个实例都会有一份。
- 设计原则:静态成员适合于那些与类的状态无关,仅需通过类本身访问的功能或数据。
- 访问限制:静态成员不能通过实例访问,这是保持设计清晰和减少误用的一种方式。
综上所述,静态方法和属性为JavaScript类的设计提供了额外的灵活性和功能,特别适用于那些全局工具函数或类级常量的场景。正确使用静态成员,可以使代码更加整洁高效。
🔄 Getter 和 Setter 解析
Getter和Setter是JavaScript类中用于定义访问和修改对象属性的特殊方法,它们为属性访问提供了额外的控制层,允许在获取或设置属性值时执行自定义逻辑,如数据验证、格式化或触发副作用。这种机制被称为“访问器属性”。
基本概念
- Getter:用于读取属性值。定义时使用
get关键字,无参数,返回属性值。 - Setter:用于设置属性值。定义时使用
set关键字,有一个参数(通常是新值),用于更新属性。
示例代码分析
class Product {constructor(price) {// 使用下划线前缀是一种约定,表示这个属性应该是“受保护”的或内部使用的this._price = price;}// Getter方法,获取价格get price() {return this._price;}// Setter方法,设置价格,包含验证逻辑set price(newValue) {// 验证价格是否为正数if (newValue < 0) {throw new Error('Price cannot be negative');}// 通过验证后,更新价格this._price = newValue;}
}// 创建Product实例
const product = new Product(10);// 使用getter读取价格
console.log(product.price); // 输出: 10// 尝试使用setter设置负价格,这将触发错误
try {product.price = -5;
} catch (error) {console.error(error.message); // 输出: Price cannot be negative
}
重要用途
- 数据验证:在setter中添加条件检查,确保数据的合法性,如上述示例中确保价格非负。
- 属性转换:在getter或setter中转换数据格式,例如,将内部存储的日期转换为字符串输出。
- 触发事件:当属性值改变时,可以在setter内部触发自定义事件或执行其他操作。
- 封装实现:隐藏属性的实际存储方式或逻辑,提供简洁的公共接口。
注意事项
- Getter和Setter应成对出现,以便提供一致的访问控制机制。
- 使用下划线前缀(如
_price)是一种常见的做法,用于区分私有或受保护的属性,但JavaScript本身并不强制私有性。 - 从ES6开始,可以使用私有字段(如
#price)来实现更严格的封装,但请注意,私有字段不能直接定义getter和setter。
通过getter和setter,开发者可以灵活地管理对象状态,增强代码的健壮性和可维护性,是实现面向对象设计中封装原则的有效手段。
📚 总结
在JavaScript中,class语法作为一种面向对象编程的结构化方式,为创建可复用、易于维护的代码提供了强大支持。
-
构造函数 (
Constructor):- 负责初始化新创建的类实例,自动在使用
new关键字实例化时调用。 - 可以接收参数并使用
this关键字为实例分配属性。 - 是类定义中的核心入口点,奠定了实例的基础状态。
- 负责初始化新创建的类实例,自动在使用
-
私有字段与方法 (
Private Fields & Methods):- ES2022 引入了私有字段与方法,通过在名称前加
#来声明,增强了类的封装性。 - 私有字段和方法仅能在类内部访问,外部代码无法直接触及,确保了数据安全和实现细节的隐藏。
- 促进良好的封装实践,限制了对内部状态的不当修改。
- ES2022 引入了私有字段与方法,通过在名称前加
-
继承 (
Inheritance):- 使用
extends关键字实现类的继承,子类能继承父类的属性和方法。 super关键字允许子类调用父类的构造函数和方法,支持方法覆盖以实现具体化或优化。- 构建类的层次结构,促进代码复用和模块化设计。
- 使用
-
静态方法与属性 (
Static Methods and Properties):- 通过
static关键字定义,直接通过类名访问,不依赖于类的实例。 - 适用于类级别操作和常量数据,如工具函数和配置项。
- 提高代码组织性和效率,避免了每次实例化时的资源消耗。
- 通过
-
Getter和Setter:
- 提供了一种控制属性访问和修改的机制,增加逻辑验证和灵活性。
- Getter用于获取属性值,Setter用于设置属性值,并可嵌入验证逻辑。
- 有助于实现数据验证、格式化和封装,保持数据一致性与安全。
综上所述,JavaScript的
class语法通过构造函数、私有特性、继承机制、静态成员以及getter和setter,为开发者提供了一套完整的面向对象编程工具集,支持构建复杂而结构化的应用程序。这些特性不仅提升了代码的可读性和可维护性,也促进了面向对象设计原则在JavaScript中的应用。
🔐 相关链接
- JavaScript中call、apply与bind详解: JavaScript中call、apply与bind的区别以及使用
- JavaScript数组常用方法: JavaScript数组全方位探索指南
相关文章:
JavaScript 中的 Class 类
🔥 个人主页:空白诗 文章目录 🔥 引言🎯 基础知识🏗️ 构造函数 (Constructor)🔐 私有字段 (Private Fields)🔐 私有方法 (Private Methods)🧬 继承 (Inheritance)📦 静态…...
python实验三 实现UDP协议、TCP协议进行服务器端与客户端的交互
实验三 实验题目 1、请利用生成器构造一下求阶乘的函数Factorial(),定义一个函数m(),在m()中调用生成器Factorial()生成小于100的阶乘序列存入集合s中,输出s。 【代码】 def factorial():n1f1while 1: f * n yield (f) n1…...
ServiceNow 研究:通过RAG减少结构化输出中的幻觉
论文地址:https://arxiv.org/pdf/2404.08189 原文地址:rag-hallucination-structure-research-by-servicenow 在灾难性遗忘和模型漂移中,幻觉仍然是一个挑战。 2024 年 4 月 18 日 灾难性遗忘: 这是在序列学习或连续学习环境中出现…...
ADS基础教程10-多态性(动态模型选择)
目录 一、多态性定义二、操作步骤1.模型建立2.模型选择3.执行仿真 一、多态性定义 ADS中支持一个Symbol中,可以同时存在多个子图。在仿真时可以动态选择不同的子图继续宁仿真。 二、操作步骤 1.模型建立 在上一章A…...
代码随想录第四十六天|单词拆分
题目链接:. - 力扣(LeetCode)...
RabbitMQ的介绍和使用
1.同步通讯和异步通讯 举个例子,同步通讯就像是在打电话,因此它时效性较强,可以立即得到结果,但如果你正在和一个MM打电话,其他MM找你的话,你们之间是不能进行消息的传递和响应的 异步通讯就像是微信&#…...
前端get请求日期类型参数向后端传参失败
1、背景 get请求,通过url上传参,因此日期类型是string类型数据 2、异常信息 nested exception is org.springframework.core.convert.ConversionFailedException: Failed to convert from type [java.lang.String] to type [java.time.LocalDate] for…...
【docker 】 push 镜像提示:denied: requested access to the resource is denied
往 Docker Registry (私服)push 镜像提示:denied: requested access to the resource is denied 镜像push 语法:docker push <registry-host>:<registry-port>/<repository>:<tag> docker push 192.16…...
浏览器各类好用插件使用及常见问题(技巧)总结
目录 Vimium C快捷键问题为什么Vimium C - 全键盘操作浏览器插件在百度页面中, x ,o,f等快捷键不起作用如何使用viminum c插件进行自定义快捷键?vimucm 为什么在浏览器首页时快捷键不起作用? 网页截图问题firefox 网页截图使用 idm问题浏览器点击idm 不下载? 待续、更新中 V…...
Python批量计算多张遥感影像的NDVI
本文介绍基于Python中的gdal模块,批量基于大量多波段遥感影像文件,计算其每1景图像各自的NDVI数值,并将多景结果依次保存为栅格文件的方法。 如下图所示,现在有大量.tif格式的遥感影像文件,其中均含有红光波段与近红外…...
6.k8s中的secrets资源
一、Secret secrets资源,类似于configmap资源,只是secrets资源是用来传递重要的信息的; secret资源就是将value的值使用base64编译后传输,当pod引用secret后,k8s会自动将其base64的编码,反编译回正常的字符…...
git 更换远程仓库地址三种方法总结
git 更换远程仓库地址三种方法总结 一、前言 由于私服的 gitlab 的地址变更,导致部分项目代码提交不上去,需要修改远端仓地址。 其它需要修改远程仓地址的情况如:切换git clone 协议由ssh变为https。 二、环境 windows 10git version 2.3…...
快速找出存(不存在)在某个(或多个)文件的文件夹
首先,需要用到的这个工具: 度娘网盘 提取码:qwu2 蓝奏云 提取码:2r1z 想要找出有下面这个文件存在的文件夹 切换到批量文件复制版块,快捷键Ctrl5 右侧,搜索添加 选定范围,勾选搜索文件夹、包…...
Linux USB转串口设备路径的查找方法
1、USB转串口设备 USB转串口设备是在嵌入式软件开发过程中经常要使用的,常常用于对接各种各样的串口设备。如果一台linux主机上使用多个usb转串口设备时,应用程序中就需要知道自己操作的是哪个串口设备。串口设备在系统上电时,由于驱动加载的…...
【初阶数据结构】单链表之环形链表
目录标题 前言环形链表的约瑟夫问题环形链表环形链表|| 前言 前面我们已经学习了关于单链表的一些基本东西,今天我们来学习单链表的一个拓展——环形链表,我们将用力扣和牛客网上的三道题目来分析讲解环形链表问题。 环形链表的约瑟夫问题 我们首先来看…...
【积分,微分,导数,偏导数公式推导】
1. 积分 积分是微积分的一个分支,用于计算曲边梯形的面积或者变速直线运动的总距离等。积分分为不定积分和定积分。 不定积分:给出一个函数,求出其所有可能的原函数。定积分:计算一个函数在特定区间上的积分。 2. 微分 微分是…...
java:递归实现的案例
//求第20个月兔子的对数 //每个月兔子对数:1,1,2,3,5,8 public class Test {//求第20个月兔子的对数//每个月兔子对数:1,1,2,3,5,8pu…...
Arxml文件解析03- 自动驾驶Radar服务radar_svc.arxml
<AR-PACKAGES><AR-PACKAGE><SHORT-NAME>bosch</SHORT-NAME><AR-PACKAGES>...</AR-PACKAGES>...
Elasticsearch安装步骤
引言 Elasticsearch是一个基于Lucene构建的开源、分布式、RESTful搜索和分析引擎。它设计用于云计算中,能够达到实时搜索,稳定,可靠,快速,安装使用方便。Elasticsearch为所有类型的数据提供近乎实时的搜索和分析。无论…...
Windows系统和unbtun系统连接usb 3.0海康可见MVS和红外艾睿相机
一.海康可见USB3.0工业面阵相机 海康usb相机需要去海康官网上下载对应系统的MVS客户端及SDK开发包 海康机器人-机器视觉-下载中心 选择Windows系统和unbtun(我是linux aarch64,所以选择了对应压缩包解压) Windows系统 1.双击安装包进入安装界面&…...
【Axure高保真原型】引导弹窗
今天和大家中分享引导弹窗的原型模板,载入页面后,会显示引导弹窗,适用于引导用户使用页面,点击完成后,会显示下一个引导弹窗,直至最后一个引导弹窗完成后进入首页。具体效果可以点击下方视频观看或打开下方…...
web vue 项目 Docker化部署
Web 项目 Docker 化部署详细教程 目录 Web 项目 Docker 化部署概述Dockerfile 详解 构建阶段生产阶段 构建和运行 Docker 镜像 1. Web 项目 Docker 化部署概述 Docker 化部署的主要步骤分为以下几个阶段: 构建阶段(Build Stage):…...
TDengine 快速体验(Docker 镜像方式)
简介 TDengine 可以通过安装包、Docker 镜像 及云服务快速体验 TDengine 的功能,本节首先介绍如何通过 Docker 快速体验 TDengine,然后介绍如何在 Docker 环境下体验 TDengine 的写入和查询功能。如果你不熟悉 Docker,请使用 安装包的方式快…...
Spring Boot 实现流式响应(兼容 2.7.x)
在实际开发中,我们可能会遇到一些流式数据处理的场景,比如接收来自上游接口的 Server-Sent Events(SSE) 或 流式 JSON 内容,并将其原样中转给前端页面或客户端。这种情况下,传统的 RestTemplate 缓存机制会…...
ardupilot 开发环境eclipse 中import 缺少C++
目录 文章目录 目录摘要1.修复过程摘要 本节主要解决ardupilot 开发环境eclipse 中import 缺少C++,无法导入ardupilot代码,会引起查看不方便的问题。如下图所示 1.修复过程 0.安装ubuntu 软件中自带的eclipse 1.打开eclipse—Help—install new software 2.在 Work with中…...
JUC笔记(上)-复习 涉及死锁 volatile synchronized CAS 原子操作
一、上下文切换 即使单核CPU也可以进行多线程执行代码,CPU会给每个线程分配CPU时间片来实现这个机制。时间片非常短,所以CPU会不断地切换线程执行,从而让我们感觉多个线程是同时执行的。时间片一般是十几毫秒(ms)。通过时间片分配算法执行。…...
docker 部署发现spring.profiles.active 问题
报错: org.springframework.boot.context.config.InvalidConfigDataPropertyException: Property spring.profiles.active imported from location class path resource [application-test.yml] is invalid in a profile specific resource [origin: class path re…...
深入浅出深度学习基础:从感知机到全连接神经网络的核心原理与应用
文章目录 前言一、感知机 (Perceptron)1.1 基础介绍1.1.1 感知机是什么?1.1.2 感知机的工作原理 1.2 感知机的简单应用:基本逻辑门1.2.1 逻辑与 (Logic AND)1.2.2 逻辑或 (Logic OR)1.2.3 逻辑与非 (Logic NAND) 1.3 感知机的实现1.3.1 简单实现 (基于阈…...
宇树科技,改名了!
提到国内具身智能和机器人领域的代表企业,那宇树科技(Unitree)必须名列其榜。 最近,宇树科技的一项新变动消息在业界引发了不少关注和讨论,即: 宇树向其合作伙伴发布了一封公司名称变更函称,因…...
手机平板能效生态设计指令EU 2023/1670标准解读
手机平板能效生态设计指令EU 2023/1670标准解读 以下是针对欧盟《手机和平板电脑生态设计法规》(EU) 2023/1670 的核心解读,综合法规核心要求、最新修正及企业合规要点: 一、法规背景与目标 生效与强制时间 发布于2023年8月31日(OJ公报&…...
