类Class面向对象的新写法class是 JavaScript 中面向对象编程的语法糖让构造函数和继承的写法更清晰、更接近传统面向对象语言的习惯。学习目标读完本文你将学会class 的基本语法声明、构造函数、方法继承 extends 和方法重写静态属性和私有字段getter/setter 的优雅写法class 与传统原型链写法的对比一、class 基础语法1.1 声明一个类classUser{constructor(name,age){this.namename;this.ageage;}greet(){console.log(你好我是${this.name});}}constusernewUser(小明,18);user.greet();// 你好我是 小明注意class 本质上是函数的语法糖。typeof User的结果是function。1.2 类表达式类也可以用表达式定义constAnimalclass{constructor(type){this.typetype;}};// 立即执行的类表达式constpersonnewclass{constructor(name){this.namename;}}(小明);1.3 传统写法对比下面是传统构造函数与 class 写法的对比// 传统方式functionUserOld(name){this.namename;}UserOld.prototype.greetfunction(){console.log(你好this.name);};// class 方式classUserNew{constructor(name){this.namename;}greet(){console.log(你好${this.name});}}两种写法功能等价但 class 更简洁、可读性更好。二、类的方法与属性2.1 实例方法类中定义的方法会自动放在原型上classCalculator{constructor(value0){this.valuevalue;}add(n){this.valuen;returnthis;// 支持链式调用}subtract(n){this.value-n;returnthis;}getResult(){returnthis.value;}}constcalcnewCalculator(10);calc.add(5).subtract(3);console.log(calc.getResult());// 122.2 静态方法与属性静态方法属于类本身不需要实例化就能调用classMathUtil{staticPI3.14159;staticadd(a,b){returnab;}staticcircleArea(r){returnthis.PI*r*r;// this 指向 MathUtil}}console.log(MathUtil.add(2,3));// 5console.log(MathUtil.circleArea(2));// 12.56636静态方法常用于工具函数、工厂方法classUser{constructor(name){this.namename;this.createdAtnewDate();}// 工厂方法从 JSON 创建用户staticfromJSON(json){constusernewUser(json.name);user.createdAtnewDate(json.createdAt);returnuser;}}constuserUser.fromJSON({name:小明,createdAt:2026-01-01});三、继承 extends3.1 基本继承用extends实现继承用super()调用父类构造函数classAnimal{constructor(name){this.namename;}speak(){console.log(${this.name}发出声音);}}classDogextendsAnimal{constructor(name,breed){super(name);// 必须调用 super()this.breedbreed;}speak(){super.speak();// 调用父类方法console.log(${this.name}汪汪叫);}}constdognewDog(旺财,柯基);dog.speak();// 旺财 发出声音// 旺财 汪汪叫注意子类的构造函数中必须调用super()且要在使用this之前调用super.method()调用父类实例方法super()调用父类构造函数3.2 继承内置类可以继承内置的 Array、Map、Error 等classPowerArrayextendsArray{isEmpty(){returnthis.length0;}}constarrnewPowerArray(1,2,3);console.log(arr.isEmpty());// false四、私有字段与私有方法4.1 私有字段# 前缀ES2022 引入了真正的私有字段只能在类内部访问classBankAccount{#balance0;// 私有字段constructor(initialBalance){this.#balanceinitialBalance;}deposit(amount){if(amount0){this.#balanceamount;}}withdraw(amount){if(amount0amountthis.#balance){this.#balance-amount;returnamount;}return0;}getBalance(){returnthis.#balance;}}constaccountnewBankAccount(100);account.deposit(50);console.log(account.getBalance());// 150// 下面两行会报错// console.log(account.#balance); // SyntaxError// account.#balance 999999; // SyntaxError4.2 私有方法classUser{#password;constructor(name,password){this.namename;this.#passwordpassword;}#hashPassword(pwd){// 私有方法returnhashed_pwd;}checkPassword(input){returnthis.#hashPassword(input)this.#hashPassword(this.#password);}}五、getter 与 settergetter 和 setter 让属性的访问和赋值像普通属性一样自然classRectangle{#width;#height;constructor(width,height){this.#widthwidth;this.#heightheight;}// gettergetarea(){returnthis.#width*this.#height;}getwidth(){returnthis.#width;}// setter带验证setwidth(value){if(value0)thrownewError(宽度必须为正数);this.#widthvalue;}setheight(value){if(value0)thrownewError(高度必须为正数);this.#heightvalue;}}constrectnewRectangle(5,3);console.log(rect.area);// 15像属性一样访问rect.width10;// 调用 setterconsole.log(rect.area);// 30// rect.width -5; // 报错宽度必须为正数六、class 表达式与动态类名functioncreateClass(className){returnclass{getName(){returnclassName;}};}constMyClasscreateClass(DynamicClass);constinstancenewMyClass();console.log(instance.getName());// DynamicClass七、常见误区与注意点误区正确理解class 中可以直接定义属性ES2022 之前需要在 constructor 中用this.x ...ES2022 支持类字段class 有提升hoistingclass 没有提升必须先定义后使用像 let/constclass创建的是一个对象class创建的是一个函数构造函数new 才创建对象省略 constructor 会报错可以省略 constructorJS 会自动添加空的 constructor箭头函数在类中自动绑定 this类字段形式的箭头函数可以但原型上的方法不行类字段与原型方法的 this 问题classButton{constructor(label){this.labellabel;}// 原型方法this 取决于调用方式handleClick(){console.log(this.label);}// 类字段箭头函数this 始终绑定实例handleClickBound(){console.log(this.label);};}constbtnnewButton(提交);constfnbtn.handleClick;// fn(); // 报错this 是 undefined严格模式constfn2btn.handleClickBound;fn2();// 提交 ✓八、动手练习练习 1实现一个 Person 类创建一个Person类属性name、age方法introduce()返回我是小明今年18岁静态方法isAdult(age)判断年龄是否 18参考答案classPerson{constructor(name,age){this.namename;this.ageage;}introduce(){return我是${this.name}今年${this.age}岁;}staticisAdult(age){returnage18;}}constpnewPerson(小明,18);console.log(p.introduce());// 我是小明今年18岁console.log(Person.isAdult(16));// false练习 2继承实现 Employee 类Employee继承Person增加属性salary方法introduce()重写为我是小明今年18岁月薪8000元参考答案classEmployeeextendsPerson{constructor(name,age,salary){super(name,age);this.salarysalary;}introduce(){return${super.introduce()}月薪${this.salary}元;}}constenewEmployee(小明,18,8000);console.log(e.introduce());练习 3带私有字段的计数器实现一个Counter类私有字段#count方法increment()、decrement()、getValue()不允许外部直接修改#count参考答案classCounter{#count0;increment(){this.#count;}decrement(){this.#count--;}getValue(){returnthis.#count;}}constcnewCounter();c.increment();c.increment();console.log(c.getValue());// 2九、AI 辅助学习9.1 本节知识点的 AI 提问模板【背景】我是 JavaScript 初学者正在学习第 22 篇类Class。 我已经了解对象、构造函数和原型链的基本概念。 【问题】我听说 class 只是语法糖本质上还是原型继承。那在实际开发中 class 语法相比传统的构造函数prototype 写法除了语法更优雅之外 还有什么实质性的优势或差异 【期望】请对比 class 和传统写法在以下方面的差异类继承的可读性、 私有字段的支持、静态属性和方法、this 绑定问题。 给出 class 写法的最佳实践建议。9.2 用 AI 验证你的理解问 AI“class 中定义的箭头函数方法和普通方法有什么区别this 绑定有何不同”让 AI 解释“为什么子类构造函数中必须先调用 super() 才能使用 this”让 AI 出题“写一道关于 getter/setter 和直接属性访问的面试题”9.3 警惕 AI 的常见错误AI 可能写出class User { name 小明; }却不说明这是 ES2022 语法AI 可能忘记提及 class 没有提升hoistingAI 可能在子类构造函数中先使用 this 再调用 super()AI 可能声称私有字段#field可以在类外部访问实际上会报错十、配套代码本文示例代码位于CODE/22-类/文件名说明class-playground.html类语法交互式游乐场创建类、继承、私有字段、getter/setter十一、本章小结class 声明class Name { constructor() {} method() {} }继承extendssuper()方法重写直接覆盖即可静态成员static method()和static prop value属于类本身私有字段#field和#method()只能在类内部访问getter/setter用get/set定义访问像普通属性本质class 是构造函数的语法糖底层仍是原型链十二、下篇预告下一篇进入异步编程《异步编程回调函数与 Promise》你将学到同步 vs 异步为什么需要异步回调函数和回调地狱Promise 的三种状态与链式调用async/await 的前奏如果本文对你有帮助欢迎点赞、收藏、关注专栏。有任何问题可以在评论区交流