• 基本上,ES6 的class可以看作只是一个语法糖,它的绝大部分功能,ES5 都可以做到,新的class写法只是让对象原型的写法更加清晰、更像面向对象编程的语法而已
  • ES6 的类,完全可以看作构造函数的另一种写法
  • 一个类必须有constructor方法,如果没有显式定义,一个空的constructor方法会被默认添加。
  • 类的属性名,可以采用表达式
  • 类不存在变量提升
  • 严格模式下,this指向为undefined
  • static关键字定义类的静态方法。
  • 如果静态方法包含this关键字,这个this指的是类,而不是实例
  • 静态方法可以与非静态方法重名
  • 父类的静态方法,可以被子类继承
  • 实例属性除了放在constructor外的另一种写法
class IncreasingCounter {
  _count = 0;
  get value() {
    console.log('Getting the current value!');
    return this._count;
  }
  increment() {
    this._count++;
  }
}
// 同时推荐这种写法,比较直观看出有哪些实例属性
class foo {
  bar = 'hello';
  baz = 'world';

  constructor() {
    // ...
  }
}
  • 类的默认行为
class Point {
}

// 等同于
class Point {
  constructor() {}
}

静态属性的提案

// 需要摒弃的写法,不符合代码应该放在一起的组织原则。
// 老写法
class Foo {
  // ...
}
Foo.prop = 1;

// 新写法
class Foo {
  static prop = 1;
}
  • super关键字只能在extends中使用。
  • 用new.target可用来约束类只能被继承。
  • 和ES5的区别
  1. 原型上的方法不可枚举

静态属性、静态方法

定义:只能在类上直接调用, 该方法不会被实例继承。

用法

class F {
    static a = 1;
    static sayHi () {
        console.log('hi')
    }
}
F.sayHi() // 'hi'
F.a // 1

私有属性、私有方法

定义:只能在类的内部访问的方法和属性,外部不能访问。ES6不支持,用下面三种方式模拟,第四种是新提案支持。

  1. symbol
  2. 将方法移出类外
  3. 下划线
  4. #新提案

用法

class Foo {
  #a;
  #b;
  constructor(a, b) {
    this.#a = a;
    this.#b = b;
  }
  #sum() {
    return #a + #b;
  }
  printSum() {
    console.log(this.#sum());
  }
}

静态私有属性、静态私有方法

定义:私有属性和私有方法前面,也可以加上static关键字,表示这是一个静态的私有属性或私有方法

class FakeMath {
  static PI = 22 / 7;
  static #totallyRandomNumber = 4;

  static #computeRandomNumber() {
    return FakeMath.#totallyRandomNumber;
  }

  static random() {
    console.log('I heard you like random numbers…')
    return FakeMath.#computeRandomNumber();
  }
}

FakeMath.PI // 3.142857142857143
FakeMath.random()
// I heard you like random numbers…
// 4
FakeMath.#totallyRandomNumber // 报错
FakeMath.#computeRandomNumber() // 报错