ES6 class 类的总结

285 阅读2分钟

类 是基于原型的继承的语法糖,类语法不会为JavaScript引入新的面向对象的继承模型

定义类

类语法有两个组成部分:类表达式和类声明

类声明

使用带有class关键字的类名(这里是“Animal”)
class Animal {
  constructor(color) {
    this.color = color
  }
}

提升:类声明不会提升,需要先声明类,然后才能访问它,否则会报错
let p = new Animal();   // ReferenceError
class Animal {}

类表达式

类表达式是定义一个类的一种方式,可以是具名或匿名的
具名类表达式的名称是类内的一个局部属性,可以通过类本身(而不是类实例)的name属性来获取

匿名类
let Animal = class {
  constructor(color) {
    this.color = color;
  }
};
console.log(Animal.name);    //Animal
具名类
let Animal = class Animal2 {
  constructor(color) {
    this.color = color;
  }
};
console.log(Animal.name);    //Animal

构造函数

constructor方法用于创建和初始化一个由class创建的对象
一个类只能有一个constructor方法,如果一个类有多个constructor,则会报错
一个构造函数可以使用 super 关键字来调用一个父类的构造函数

实例属性

实例的属性必须定义在类的方法里
class Animal {
  constructor(color) {
    this.color = color
  }
}

extends 继承,使用extends创建子类

extends 在类声明或类表达式中,用于创建一个类作为另一个类的一个子类
如果子类中定义了构造函数,那么它必须先调用 super() 才能使用 this 

class Animal{
  constructor(name){
    this.name = name;
  }
  wang(){
    console.log(`${this.name} say hello`);
  }
}
class Dog extends Animal{
  constructor(name){
    super(name);             //调用父类构造函数并传入name参数
  }
  wang(){
    console.log(`${this.name} say hello`);
  }
}
var d = new Dog('大黄');
d.wang();                    //'大黄 say hello'

可以继承基于函数的"类"

function Animal (name) {
  this.name = name;  
}
Animal.prototype.speak = function () {
  console.log(this.name + 'say hello');
}
class Dog extends Animal {
  speak() {
    super.speak();
    console.log(this.name + 'haha');
  }
}
var d = new Dog('大黄');
d.speak();              //大黄 say hello haha

重写构造器 species

在子类数组MyArray中返回父类Array对象,使用species覆盖默认的构造函数
例如map()返回默认构造函数的方法时,希望返回的是父Array对象,而不是MyArray对象,使用Symbol.species

class MyArray extends Array{
  static get [Symbol.species](){ return Array;}
}
var a = new MyArray(1,2,3);
var mapped = a.map(x => x*x);
console.log(mapped instanceof MyArray);   // false
console.log(mapped instanceof Array);     // true

静态方法 static

static 用来定义一个类的一个静态方法,调用静态方法不需要实例化该类
但不能通过一个类实例调用静态方法,静态方法通常用于为一个应用程序创建工具函

class Point {
    constructor(x, y) {
        this.x = x;
        this.y = y;
    }
    // 静态方法,可直接调用Point.distance(a, b)
    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只是语法糖,是原型继承的抽象形式
在创建类的新实例,必须使用关键字new