ES6 class相关内容详解

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

下面是对 ES6 class 相关内容的详细介绍:


一、基本语法

1. 定义类

javascript 复制代码
class MyClass {
  constructor(name) {
    this.name = name;
  }

  greet() {
    console.log(`Hello, ${this.name}!`);
  }
}
  • class 关键字用于声明一个类。
  • constructor 是类的构造函数,用于初始化实例属性。
  • 方法直接写在类体中,不需要加 function 关键字,也不需要逗号分隔。

2. 实例化

javascript 复制代码
const instance = new MyClass('Alice');
instance.greet(); // 输出: Hello, Alice!

二、类的特性

1. 严格模式

类内部默认运行在 严格模式 下,即使没有显式声明 "use strict"

2. 不可枚举的方法

类中定义的方法是 不可枚举的 (non-enumerable),这与通过 prototype 手动添加方法不同。

javascript 复制代码
console.log(Object.keys(MyClass.prototype)); // []
console.log(Object.getOwnPropertyNames(MyClass.prototype)); // ['constructor', 'greet']

3. 类声明不会提升(hoisting)

与函数声明不同,class 声明 不会被提升,必须先声明再使用。

javascript 复制代码
// ❌ 报错:Cannot access 'MyClass' before initialization
const obj = new MyClass();

class MyClass {}

三、静态方法(static)

使用 static 关键字定义属于类本身的方法,而不是实例。

javascript 复制代码
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

可以使用 getset 定义访问器属性:

javascript 复制代码
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. 基本继承

javascript 复制代码
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. 继承静态方法

子类会继承父类的静态方法:

javascript 复制代码
class Parent {
  static whoami() {
    return 'Parent';
  }
}

class Child extends Parent {}

Child.whoami(); // 'Parent'

六、类表达式

除了类声明,还可以使用类表达式:

javascript 复制代码
// 匿名类表达式
const MyClass = class {
  constructor(x) {
    this.x = x;
  }
};

// 命名类表达式(类名仅在内部可见)
const Rectangle = class Shape {
  getArea() {
    return this.width * this.height;
  }

  // Shape 只能在类内部使用(例如递归或调试)
};

七、私有字段(ES2022+,但常与 class 一起讨论)

虽然最初 ES6 没有私有字段,但后续标准(ES2022)引入了私有成员,使用 # 前缀:

javascript 复制代码
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 一起使用。


八、注意事项与常见误区

  1. class 本质仍是函数

    javascript 复制代码
    typeof MyClass; // "function"
  2. 所有方法都定义在 prototype 上

    javascript 复制代码
    MyClass.prototype.greet === instance.greet; // true
  3. 不能直接调用类(必须用 new)

    javascript 复制代码
    MyClass(); // ❌ TypeError: Class constructor cannot be invoked without 'new'
  4. 子类 constructor 中必须调用 super()(如果使用 this)

    javascript 复制代码
    class Bad extends Animal {
      constructor() {
        this.name = 'bad'; // ❌ ReferenceError: Must call super() before accessing 'this'
      }
    }

九、与传统原型写法对比

传统写法(ES5)

javascript 复制代码
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 写法

javascript 复制代码
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 开发的标准写法之一。

相关推荐
aeoliancrazy14 小时前
es6迭代器(Iterator的使用),遇到的问题理解,数组属性相关的一点小细节
前端·javascript·es6
ZouZou老师15 小时前
C++设计模式之原型模式:以家具生产为例
c++·设计模式·原型模式
lcc18715 小时前
ES6 Symbol
es6
m0_471199631 天前
【JavaScript】Set 和 Map 核心区别与实战用法(ES6 集合全解析)
前端·javascript·es6
还是大剑师兰特1 天前
制作思维导图的在线网站及软件工具(10种)
思维导图·大剑师
还是大剑师兰特2 天前
压缩图片的10种方法(线上+线下)
大剑师·压缩图片
San30.2 天前
从原型链到“圣杯模式”:JavaScript 继承方案的演进与终极解法
开发语言·javascript·原型模式
BlackWolfSky2 天前
ES6 学习笔记3—7数值的扩展、8函数的扩展
前端·javascript·笔记·学习·es6
lcc1872 天前
ES6 箭头函数
es6