ECMAScript 2015 中引入的 JavaScript 类实质上是 JavaScript 现有的基于原型的继承的语法糖。类语法不会为JavaScript引入新的面向对象的继承模型。
定义类
定义类有两种方式,一个是通过 类声明 的方式,另外一种是通过 类表达式 来定义。
类声明
类似于函数声明一样,我们可以通过带有 class
的关键字的类名来定义。
class Rectangle{
constructor(height,width){
this.height = height;
this.weight = width
}
}
提升
函数声明 和 类声明 中有一个重要的区别是,函数声明可以提升,而类声明不行(同样地,在函数表达式中和类表达式中同样不行)。
因此,类似这样的代码将会抛出异常。
let p = new Rectangle(10,10);
// ReferenceError
class 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;
}
// getter
get 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.');
}
}