ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。
定义类
定义类有两种方式,一个是通过 类声明 的方式,另外一种是通过 类表达式 来定义。
类声明
类似于函数声明一样,我们可以通过带有 class 的关键字的类名来定义。
class Rectangle{constructor(height,width){this.height = height;this.weight = width}}
提升
函数声明 和 类声明 中有一个重要的区别是,函数声明可以提升,而类声明不行(同样地,在函数表达式中和类表达式中同样不行)。
因此,类似这样的代码将会抛出异常。
let p = new Rectangle(10,10);// ReferenceErrorclass Rectangle{constructor(height,width){this.height = height;this.width = width;}}
类表达式
一个类表达式是定义一个类的另一种方式。
// 匿名let Rectangle = class {constructor(height, width){this.height = height;this.width = width;}}// 被命名let Rectangle = class Rectangle{constructor(height, width){this.height = height;this.width = width;}}
类体和方法定义
原型方法
class R{constructor(width,height){this.width = width;this.height = height;}// getterget area(){return this.calcArea()}calcArea(){return this.width*this.height}}let a = new R(10,10);console.log(a.area)// 100
这里需要注意几点。
- 在类定义中,构造函数、方法等其他语句块中,不用像对象里用 “,” 分割开来,其次,在 getter 中的函数不用加括号()。
静态方法
static 关键字用来定义一个类的一个静态方法。调用静态方法不需要 实例化 这个类, 且不能通过类的实例对象来调用这个静态方法 。
class Point {constructor(x, y) {this.x = x;this.y = y;}static distance(a, b) {const dx = a.x - b.x;const dy = a.y - b.y;return Math.hypot(dx, dy);}}const p1 = new Point(5, 5);const p2 = new Point(10, 10);console.log(Point.distance(p1, p2));
字段声明
字段声明分为共有字段和私有字段
公有字段
class Rectangle{width = 10;height;constructor(width,height){this.width = width;this.height = height;}}
私有字段
class Rectangle{#width = 10;#height;constructor(width,height){this.#width = width;this.#height = height;}}
从类外部引用私有字段将是错误的,它们只能在类里读取或写入。
子类
我们使用 extends 来创建子类
class Animal{constructor(name){this.name = name}speak(){console.log(this.name + "makes a noise");}}class Dog extends Animal{// 可以没有这中间的部分,那么 Dog 类将于 Animal 类完全拥有相同的属性与方法speak(){console.log(this.name + "barks" )}}let d = new Dog("Xirui");d.speak(); // Xirui barks
使用 super 调用超类
class Cat {constructor(name) {this.name = name;}speak() {console.log(this.name + ' makes a noise.');}}class Lion extends Cat {speak() {super.speak(); // 调用类父类的方法console.log(this.name + ' roars.');}}
