Class

70 阅读4分钟

ES6中的Class与继承

Class的特点

  • ES6的class可以看作是一种语法糖,它实质上还是基于原型的面向对象编程的一种封装。
  • 方法与方法之间不需要逗号分隔,定义方法的时候前面不需要加上function关键字。
  • 类的内部所有定义的方法,都是不可枚举的(non-enumerable)。
  • 类必须使用new调用,否则会报错。
  • 类的属性和方法,除非显式定义在其本身(即定义在this对象上),否则都是定义在原型上(即定义在class上)。
  • 类的所有实例共享一个原型对象。
  • 在“类”的内部可以使用getset关键字,对某个属性设置存值函数和取值函数,拦截该属性的存取行为。
  • 类的属性名可以采用表达式的形式定义,也可以使用表达式作为类的名称。

继承

  • 使用extends关键字实现继承,子类可以继承父类的属性和方法。
  • 子类必须在constructor()方法中调用super(),否则会报错。super()用于调用父类的构造函数,确保子类实例继承父类的属性和方法。
  • 在子类的构造函数中使用super()之后,才能使用this关键字。
  • 父类的静态方法可以被子类继承。
  • 子类的静态方法中使用super调用父类的静态方法时,方法内部的this指向当前子类,而不是子类的实例。
  • 子类继承父类后,如果子类没有定义constructor()方法,将默认添加一个空的constructor()方法。
  • ES6的继承是通过软拷贝实现的,父类的属性和方法被复制到子类上。修改子类的属性或方法不会影响到父类。

使用super关键字

  • super作为函数使用时,代表父类的构造函数。子类的构造函数中必须执行一次super()
  • super作为对象使用时,在普通方法中指向父类的原型对象,在静态方法中指向父类本身。
  • 使用super调用父类的方法时,方法内部的this指向当前的子类实例。
  • 为了避免this指向错误,使用super的时候必须显式指定是作为函数、还是作为对象使用,否则会报错。

new.target属性

  • new.target是一个内置的元属性,用于确定构造函数是怎么调用的。
  • 当构造函数使用new命令调用或Reflect.construct()调用时,new.target会返回被调用的构造函数。
  • 子类继承父类时,new.target会返回子类。

类的注意点

  • 类和模块的内部,默认就是严格模式,所以不需要使用use strict指定运行模式。
  • 类不存在变量提升,子类必须保证在父类之后定义。
  • 类的name属性总是返回紧跟在class关键字后面的类名。
  • 类的内部调用new.target,返回当前类。
  • 子类继承父类时,new.target会返回子类。

私有属性和私有方法

  • ES2022正式为class添加了私有属性和私有方法,私有属性的属性名必须包括#,如果不带#,会被当作另一个属性。
  • 私有属性和私有方法可以设置getset方法。
  • 私有属性不限于从this引用,只要是在类的内部,实例也可以引用私有属性。
  • 静态方法和私有方法的区别是,静态方法作为类的属性,不会被实例继承,而私有方法是定义给当前类内部使用,其子类不可以调用。

in运算符

  • in运算符可以用来判断私有属性是否存在,返回一个布尔值。
  • in运算符对于Object.create()Object.setPrototypeOf形成的继承,是无效的,因为这种继承不会传递私有属性。

静态块

  • 类的内部有一个static代码块,它的好处是将静态属性的初始化逻辑写入类的内部,而且只运行一次。
  • 每个类允许有多个静态块,每个静态块中只能访问之前声明的静态属性。静态块的内部不能有return语句。
  • 静态块内部可以使用类名或this,指代当前类。