通俗解释ES6语法中的类与继承机制

搞懂 ES6 的class和继承:从写代码的“土办法”到优雅编程

你有没有过这样的经历?在早期写 JavaScript 时,想做个“人”这个对象,结果只能靠函数模拟:

function Person(name, age) { this.name = name; this.age = age; } Person.prototype.sayHello = function() { console.log(`Hello, I'm ${this.name}`); };

看着像那么回事,但总觉得别扭——明明是面向对象的思想,语法却像是拼凑出来的。更头疼的是,一旦要搞个学生、老师这些子类,就得手动操作原型链,一不小心就出错。

直到 ES6 出现了class关键字,一切都变了。


为什么我们需要class

随着前端项目越来越复杂,单靠对象字面量和函数已经撑不住了。React、Vue 这些框架开始流行组件化开发,我们迫切需要一种更清晰、更有组织性的方式来管理代码逻辑。

ES6 的class就是在这种背景下诞生的。它不是新发明了一套继承机制,而是给老的原型继承穿上了一件漂亮的新外衣——也就是常说的“语法糖”。但它这件衣服穿得太好看了,以至于很多人以为 JavaScript 突然变成了 Java 那样的语言。

其实不然。class只是让原本晦涩难懂的原型操作变得直观易读了。


class到底怎么用?一个例子讲明白

来看一个最简单的例子:

class Person { constructor(name, age) { this.name = name; this.age = age; } sayHello() { console.log(`Hello, I'm ${this.name}`); } static info() { console.log('This is a Person class'); } }

这段代码做了三件事:
-构造函数constructor:创建实例时自动执行,用来初始化属性;
-实例方法sayHello():每个由new Person()创建的对象都能调用;
-静态方法info():属于类本身,不归实例所有,直接通过Person.info()调用。

使用起来也很简单:

const p = new Person("Alice", 30); p.sayHello(); // 输出: Hello, I'm Alice Person.info(); // 输出: This is a Person class

注意:你不能直接调用Person(),必须用new,否则会报错。这是强制规范,防止误用。


class背后还是原型链,只是你看不见

虽然写法看起来像 Java 或 C++,但底层依然是 JavaScript 原有的那一套——基于原型(prototype-based)的对象系统。

当你写下class Person,JavaScript 实际上做了这些事:

  1. Person当作一个函数(构造器);
  2. 把所有实例方法(如sayHello)挂到Person.prototype上;
  3. 静态方法则直接挂在Person函数上;
  4. new实例化时,执行constructor,并把this绑定到新对象。

所以,下面这行代码依然成立:

p.__proto__ === Person.prototype; // true

也就是说,方法查找还是走原型链的老路子。class只是帮你省去了手动写Person.prototype.sayHello = ...的麻烦。


让数据更安全:getter 和 setter

有时候你不希望别人随意修改某些属性,比如银行账户余额。这时候可以用getset来控制访问。

class BankAccount { constructor(initialBalance = 0) { this._balance = initialBalance; // _ 表示“私有”约定 } get balance() { return this._balance; } set balance(amount) { if (amount < 0) throw new Error("Balance cannot be negative"); this._balance = amount; } deposit(money) { this.balance += money; } withdraw(money) { if (money > this.balance) throw new Error("Insufficient funds"); this._balance -= money; } }

现在你可以像读普通属性一样获取余额:

const account = new BankAccount(100); console.log(account.balance); // 100 account.deposit(50); console.log(account.balance); // 150 account.balance = -10; // 抛错!

这里的_balance并非真正的私有字段(ES2022 之前没有),只是一个命名约定,提醒开发者:“别在外面直接改我”。


子类怎么来?用extends实现继承

假设我们要做一个学生类,他也有人的基本信息,但多了个年级属性,还能学习。

以前你可能得复制一遍Person的代码再加点东西,但现在只需要一句话:

class Student extends Person { constructor(name, age, grade) { super(name, age); // 必须先调用父类构造函数 this.grade = grade; } study() { console.log(`${this.name} is studying...`); } // 重写父类方法 sayHello() { console.log(`Hi, I'm ${this.name}, a student in grade ${this.grade}`); } }

关键点来了:
-extends表示继承自Person
-super(name, age)是调用父类的constructor,必须在使用this之前调用;
-sayHello方法被重写了,子类优先;
- 新增了study方法,扩展功能。

试试看效果:

const s = new Student("Tom", 20, "Junior"); s.sayHello(); // Hi, I'm Tom, a student in grade Junior s.study(); // Tom is studying...

多态也生效了:

function greetEveryone(people) { people.forEach(person => person.sayHello()); } greetEveryone([ new Person("Mr. Lee", 45), new Student("Lucy", 19, "Freshman") ]); // 各自用自己的方式打招呼

继承背后的原理:原型链是如何延伸的?

你以为extends是魔法?其实它也只是帮你连好了原型链。

当你说class Student extends Person,JavaScript 在背后悄悄做了几件事:

  1. Student.prototype.__proto__ = Person.prototype
    → 所以实例方法可以向上查找;
  2. Student.__proto__ = Person
    → 所以静态方法也能继承;
  3. super()实际就是Parent.call(this, ...args)的语法糖;
  4. 方法调用遵循“就近原则”,找不到就往上找。

这也解释了为什么:

s instanceof Student; // true s instanceof Person; // true

因为instanceof查的就是原型链。


再进一步:多层继承与方法增强

你可以继续派生更具体的类,比如研究生:

class GraduateStudent extends Student { constructor(name, age, grade, researchTopic) { super(name, age, grade); this.researchTopic = researchTopic; } sayHello() { super.sayHello(); // 先执行父类逻辑 console.log(`Researching on: ${this.researchTopic}`); } static createFromStudent(student, topic) { const { name, age, grade } = student; return new GraduateStudent(name, age, grade, topic); } } const gs = new GraduateStudent("Bob", 25, "PhD", "AI Ethics"); gs.sayHello(); // 输出: // Hi, I'm Bob, a student in grade PhD // Researching on: AI Ethics

这里展示了两个高级技巧:
-调用super.sayHello():保留父类行为的同时增加新功能;
-静态工厂方法:提供更灵活的对象创建方式,封装细节。


实际应用场景:什么时候该用类?

别以为class只是用来炫技的。在真实项目中,它有很多实用场景:

✅ UI 组件定义

虽然 React 现在主推函数组件 + Hooks,但在 Vue 2 和一些老项目里,类仍然是组织组件逻辑的重要方式。

class UserCard extends Component { render() { return `<div>Hello ${this.props.name}</div>`; } }

✅ 工具类封装

比如封装一个 HTTP 请求客户端:

class HttpClient { constructor(baseURL) { this.baseURL = baseURL; } async get(url) { return fetch(this.baseURL + url).then(r => r.json()); } static createJsonPlaceholder() { return new HttpClient('https://jsonplaceholder.typicode.com'); } }

✅ 游戏或管理系统中的实体建模

在一个学生管理系统中,常见的继承结构可能是:

Person ↓ Student ↓ GraduateStudent

共用姓名、年龄等基础属性,逐级扩展能力,减少重复代码。


使用类的最佳实践:别踩这些坑

class很强大,但也容易滥用。记住这几个建议:

❌ 不要过度继承

超过两到三层的继承链会让代码难以维护。优先考虑组合代替继承

// 更好的方式:通过对象组合功能 const CanStudy = { study() { /*...*/ } }; Object.assign(Student.prototype, CanStudy);

✅ 合理使用静态方法

静态方法适合做工具函数,不要在里面引用this或实例状态。

✅ 保护内部状态

尽管 ES2022 才正式支持私有字段(#privateField),但你可以用_前缀表示“请勿外部访问”:

this._password = 'secret'; // 约定俗成

✅ 方法重写要小心

确保重写后的行为符合预期,尤其是被其他模块依赖的方法,避免破坏 Liskov 替换原则。

✅ 大项目推荐搭配 TypeScript

给类加上类型注解,能极大提升可读性和安全性:

class Person { constructor(public name: string, public age: number) {} }

总结一下:你真正需要掌握的是什么?

  • class是语法糖,本质仍是原型继承;
  • extendssuper让继承变得简洁清晰;
  • 支持构造函数、实例方法、静态方法、getter/setter 完整特性;
  • 多态和instanceof依然有效;
  • 提高了代码复用性、可读性和团队协作效率。

更重要的是:学会用类去抽象现实世界中的事物关系,而不是为了用而用。

未来,随着私有字段、装饰器等新特性的普及,JavaScript 的类模型还会变得更强大。但无论怎么变,理解其背后的原型机制,才是你驾驭这门语言的根本。

如果你正在写一个复杂的前端应用,不妨试着把核心模型抽象成类。你会发现,代码突然变得有条理了。

如果你在实现过程中遇到了其他挑战,欢迎在评论区分享讨论。

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

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

相关文章

有关HDFS的三种客户端操作方式详解 (命令行,网页界面,Java API一步到位)_hdfs客户端,收藏这篇就够了

前言 Hadoop分布式文件系统(HDFS)提供了多种客户端操作方式&#xff0c;本文将详细介绍三种主流操作方法&#xff1a;命令行操作、Web界面操作和Java API编程。通过在VMware Workstation Pro虚拟环境中使用CentOS 8系统&#xff0c;结合MobaXterm终端工具&#xff0c;我将逐一…

Thinkphp-Laravel基于微信小程序一对一教学班级作业小助手的设计与实现_7nl0d

目录摘要内容项目开发技术介绍PHP核心代码部分展示系统结论源码获取/同行可拿货,招校园代理摘要内容 针对微信小程序环境下的一对一教学班级作业管理需求&#xff0c;设计并实现了一款基于ThinkPHP和Laravel框架的作业小助手系统。该系统整合了教师端与学生端功能&#xff0c;…

手把手教你绘制RS485接口详细接线图(含MAX485)

从零开始画懂RS485接线&#xff1a;MAX485实战全解析你有没有遇到过这样的情况&#xff1f;系统明明在实验室通得好好的&#xff0c;一拉到现场300米外的设备上就丢包、乱码&#xff0c;甚至通信完全中断。排查半天发现——不是程序写错了&#xff0c;而是RS485接线图没画对。别…

I2C协议总线电容影响分析:长线传输性能下降原因

为什么你的I2C总线一拉长就通信失败&#xff1f;揭秘总线电容的“隐形杀手”效应你有没有遇到过这种情况&#xff1a;在开发板上测试得好好的I2C通信&#xff0c;传感器读数稳定、响应迅速&#xff1b;可一旦把线拉长几米&#xff0c;接上几个设备&#xff0c;就开始丢数据、报…

WinDbg加载符号文件完整指南:精准定位驱动问题

WinDbg符号加载实战指南&#xff1a;像内核工程师一样精准定位驱动崩溃 你有没有遇到过这样的场景&#xff1f;系统突然蓝屏&#xff0c;你兴冲冲打开WinDbg分析转储文件&#xff0c;结果堆栈里全是裸地址&#xff1a; fffff80003c5a120 fffff8011a2b3c4d连函数名都看不到&a…

IPD咨询洞察:别再让客户试用“踩坑”!IPD模式下的客户试用管理全流程实战指南

在IPD体系中&#xff0c;客户试用绝非简单的“产品给客户用用看”&#xff0c;而是产品大规模上市前至关重要的一次“大考”。它系统性地验证产品与市场的匹配度&#xff0c;是规避风险、优化产品、确保发布成功的核心环节。本文将为您详解客户试用的全流程管理&#xff0c;揭示…

【苍狮技术团队】2026 开年调研:大家都在用大模型做什么?大模型项目真的跑起来了?

2025 年&#xff0c;我们见证了大模型从「技术狂欢」逐渐走向「真实落地」。 这一年里&#xff0c;我们在公众号持续分享了&#xff1a; ✅ Dify 私有化部署与二次开发✅ RAGFlow 知识库构建与检索优化✅ 企业内部知识问答、流程自动化、智能助手实践✅ 模型选型、性能调优、…

全面讲解常见智能设备:门锁、灯光、传感器入门

智能家居入门&#xff1a;从门锁、灯光到传感器的实战解析你有没有过这样的经历&#xff1f;深夜回家&#xff0c;手忙脚乱掏钥匙开门&#xff0c;结果发现灯还关着——只能摸黑进屋。或者出门后突然怀疑&#xff1a;“我到底锁门了没有&#xff1f;”这些日常小烦恼&#xff0…

Android Studio 性能分析工具:优化移动应用性能

Android Studio 性能分析工具&#xff1a;优化移动应用性能关键词&#xff1a;Android Studio、性能分析工具、移动应用性能、优化、性能监测摘要&#xff1a;本文主要围绕 Android Studio 中的性能分析工具展开&#xff0c;详细介绍了这些工具的核心概念、工作原理、使用方法以…

零基础也能懂的机器学习核心概念解读

一、核心概念解读 1. 机器学习&#xff08;ML&#xff09; 专业定义&#xff1a;一门让计算机无需被明确编程就能从数据中学习并改进的学科&#xff0c;其核心是构建能从经验&#xff08;数据&#xff09;中自动提炼规律、并用于预测或决策的系统。 通俗解读&#xff1a;就像教…

网安校招党集合!3 类入门岗位薪资 + 技能对标,你们更倾向渗透测试还是安全运营?

网络安全校招&#xff1a;3 类入门岗位薪资 技能要求&#xff0c;清晰对标 2025 年网络安全人才缺口已突破 150 万&#xff0c;北京、深圳等城市企业甚至开出 “应届生年薪 30 万 ” 的高薪抢人。但对高校应届生而言&#xff0c;“岗位类型繁杂、技能要求模糊” 往往成为求职路…

电感在电源储能环节的作用深度剖析

电感如何在电源中“搬能量”&#xff1f;一文讲透它的核心角色你有没有想过&#xff0c;一个小小的电感&#xff0c;凭什么能在开关电源里稳坐C位&#xff1f;它不像MOSFET那样“掌权”通断&#xff0c;也不像控制IC那样“发号施令”&#xff0c;但它却是整个能量转换链条中最沉…

PDF-Extract-Kit保姆级指南:定期任务与自动化

PDF-Extract-Kit保姆级指南&#xff1a;定期任务与自动化 1. 引言 1.1 业务场景描述 在日常工作中&#xff0c;许多企业和个人需要处理大量PDF文档&#xff0c;如学术论文、财务报表、合同文件等。这些文档中包含丰富的结构化信息&#xff08;表格&#xff09;、数学公式、文…

2026 黑客学习避坑指南:从计算机基础到 0day 挖掘,超详细步骤 + CTF 赛事攻略,看这篇就够

2026入门黑客的正确姿势&#xff0c;从零基础入门到精通&#xff08;超详细&#xff09;&#xff0c;看这一篇就够了&#xff01; 前言 首先要明白啊&#xff0c;我们现在说的黑客不是那种窃取别人信息、攻击别人系统的黑客&#xff0c;说的是调试和分析计算机安全系统的网络…

PDF-Extract-Kit参数详解:批处理大小优化指南

PDF-Extract-Kit参数详解&#xff1a;批处理大小优化指南 1. 引言&#xff1a;PDF智能提取的工程挑战 在数字化文档处理领域&#xff0c;PDF文件因其格式稳定、跨平台兼容性强而被广泛使用。然而&#xff0c;PDF本质上是一种“展示层”格式&#xff0c;其内容结构往往难以直接…

谁懂啊!自学黑客不用瞎找书!5 本核心书单 + 免费电子书,满足你的黑客梦!

经常会有粉丝朋友私信我&#xff0c;想学黑客技术有什么书籍推荐&#xff0c;今天就给大家安利一波。 想自学黑客&#xff0c;看这五本书就够了 想要自学黑客却没人教怎么办&#xff0c;看完这五本书&#xff0c;你也能成为黑客大佬&#x1f4aa; ✅第一本《黑客攻防:从入门到…

网络安全就业指南:从入门到精通的职业路径与能力认证

网络安全就业指南&#xff1a;从入门到精通的职业路径与能力认证 声明&#xff1a;无恶意引导&#xff0c;内容来源于新闻帖子文章等&#xff0c;此文章是各大平台资源整合的结晶&#xff01; 有小伙伴私信我想了解关于网络安全行业的就业前景待遇&#xff0c;以及学习技能和…

PySide6从0开始学习的笔记(二十三)使用QRunnable在线程池中执行临时任务

简要介绍&#xff1a;QRunnable是轻量级的任务载体核心定位&#xff1a;只封装「任务逻辑」&#xff0c;不具备线程能力。QRunnable 的唯一核心作用是「打包要在子线程中执行的业务代码」&#xff0c;它只回答「要做什么」&#xff08;即 run() 方法中封装的逻辑&#xff09;&a…

AI元人文:给预印本平台的两封信——人机书写

AI元人文&#xff1a;给预印本平台的两封信——人机书写Re: 哲学社会科学预印本平台——您的论文未通过审核发件人&#xff1a;"李湖北 "收件人&#xff1a;yuyin时 间&#xff1a;2026-01-09 18:04:49其实&#xff0c;我研究预料到了&#xff0c;在四个月前&#…

UE5 C++(UObject 的实例化 19-1):保存 UObject 子类对象的相关类 TSubclassOf<U>、TObjectPtr<U>、FObjectPtr、FObjectHandle

&#xff08;99&#xff09;上面的这句&#xff0c;引用了 UE 库里的这些类&#xff0c;实现了类似于智能指针的功能 &#xff1a;&#xff08;100&#xff09; &#xff08;101&#xff09; 谢谢