ES6(ECMAScript 2015)引入了 class 语法,作为 JavaScript 中面向对象编程的一种更清晰、更接近传统语言(如 Java、C++)的语法糖。虽然底层仍然基于原型(prototype)机制,但 class 提供了一种更直观的方式来定义和使用构造函数、方法、继承等。

下面是对 ES6 class 相关内容的详细介绍:
一、基本语法
1. 定义类
class MyClass {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hello, ${this.name}!`);
}
}
class关键字用于声明一个类。constructor是类的构造函数,用于初始化实例属性。- 方法直接写在类体中,不需要加
function关键字,也不需要逗号分隔。
2. 实例化
const instance = new MyClass('Alice');
instance.greet(); // 输出: Hello, Alice!
二、类的特性
1. 严格模式
类内部默认运行在 严格模式 下,即使没有显式声明 "use strict"。
2. 不可枚举的方法
类中定义的方法是 不可枚举的(non-enumerable),这与通过 prototype 手动添加方法不同。
console.log(Object.keys(MyClass.prototype)); // []
console.log(Object.getOwnPropertyNames(MyClass.prototype)); // ['constructor', 'greet']
3. 类声明不会提升(hoisting)
与函数声明不同,class 声明 不会被提升,必须先声明再使用。
// ❌ 报错:Cannot access 'MyClass' before initialization
const obj = new MyClass();
class MyClass {}
三、静态方法(static)
使用 static 关键字定义属于类本身的方法,而不是实例。
class MathUtil {
static add(a, b) {
return a + b;
}
}
MathUtil.add(2, 3); // 5
// new MathUtil().add(2, 3); // ❌ TypeError: not a function
静态方法常用于工具函数或工厂方法。
四、getter 和 setter
可以使用 get 和 set 定义访问器属性:
class Person {
constructor(name) {
this._name = name;
}
get name() {
return this._name.toUpperCase();
}
set name(value) {
if (value.length < 2) {
throw new Error('Name too short');
}
this._name = value;
}
}
const p = new Person('alice');
console.log(p.name); // ALICE
p.name = 'Bob';
console.log(p.name); // BOB
五、继承(extends & super)
ES6 支持类的继承,使用 extends 关键字,并通过 super 调用父类的构造函数或方法。
1. 基本继承
class Animal {
constructor(name) {
this.name = name;
}
speak() {
console.log(`${this.name} makes a sound.`);
}
}
class Dog extends Animal {
constructor(name, breed) {
super(name); // 调用父类构造函数
this.breed = breed;
}
speak() {
super.speak(); // 调用父类方法
console.log(`${this.name} barks!`);
}
}
const dog = new Dog('Rex', 'Husky');
dog.speak();
// Rex makes a sound.
// Rex barks!
2. 继承静态方法
子类会继承父类的静态方法:
class Parent {
static whoami() {
return 'Parent';
}
}
class Child extends Parent {}
Child.whoami(); // 'Parent'
六、类表达式
除了类声明,还可以使用类表达式:
// 匿名类表达式
const MyClass = class {
constructor(x) {
this.x = x;
}
};
// 命名类表达式(类名仅在内部可见)
const Rectangle = class Shape {
getArea() {
return this.width * this.height;
}
// Shape 只能在类内部使用(例如递归或调试)
};
七、私有字段(ES2022+,但常与 class 一起讨论)
虽然最初 ES6 没有私有字段,但后续标准(ES2022)引入了私有成员,使用 # 前缀:
class Counter {
#count = 0; // 私有字段
increment() {
this.#count++;
}
getCount() {
return this.#count;
}
}
const c = new Counter();
c.increment();
console.log(c.getCount()); // 1
// console.log(c.#count); // ❌ SyntaxError
注意:这是 ES2022 特性,不属于原始 ES6,但现代 JS 开发中常与 class 一起使用。
八、注意事项与常见误区
-
class 本质仍是函数
typeof MyClass; // "function" -
所有方法都定义在 prototype 上
MyClass.prototype.greet === instance.greet; // true -
不能直接调用类(必须用 new)
MyClass(); // ❌ TypeError: Class constructor cannot be invoked without 'new' -
子类 constructor 中必须调用 super()(如果使用 this)
class Bad extends Animal { constructor() { this.name = 'bad'; // ❌ ReferenceError: Must call super() before accessing 'this' } }
九、与传统原型写法对比
传统写法(ES5)
function Person(name) {
this.name = name;
}
Person.prototype.greet = function() {
console.log('Hi, ' + this.name);
};
Person.species = 'Homo sapiens';
Person.getSpecies = function() {
return this.species;
};
ES6 class 写法
class Person {
constructor(name) {
this.name = name;
}
greet() {
console.log(`Hi, ${this.name}`);
}
static species = 'Homo sapiens';
static getSpecies() {
return this.species;
}
}
后者更简洁、语义更清晰。
十、总结
| 特性 | 说明 |
|---|---|
class | 语法糖,基于原型 |
constructor | 构造函数,初始化实例 |
| 方法 | 自动绑定到 prototype,不可枚举 |
static | 静态方法,属于类本身 |
extends / super | 实现继承 |
get / set | 定义访问器 |
| 无提升 | 必须先声明后使用 |
| 严格模式 | 默认启用 |
ES6 的 class 极大提升了 JavaScript 面向对象编程的可读性和可维护性,是现代前端/Node.js 开发的标准写法之一。
2168

被折叠的 条评论
为什么被折叠?



