【ES6】 class

120 阅读2分钟

传统构造函数出现的问题

  • 属性和原型方法定义分离,降低了可读性
  • 原型成员可以被枚举
  • 默认情况下,构造函数仍然可以被当作普通函数使用

概述

在ES6中,class (类)作为对象的模板被引入,可以通过 class 关键字定义类。 class 的本质是 function。

class Singer {}
console.log(typeof Singer) // function
console.log(Singer === Singer.prototype.constructor)  // true

基本用法

constructor 方法是类的默认方法,通过 new 命令生成对象实例时,会自动调用该方法。一个类必须有 constructor 方法,如果没有显式定义,会默认添加一个空的 constructor 方法

class Animal {
  constructor(name, food) {
    this.name = name
    this.food = food
  }

  say() {
    return `我是${this.name}动物,吃的是${this.food}`
  }
}

const obj = new Animal('dog', '肉肉')
console.log(obj.say()) // 我是dog动物,吃的是肉肉

类的特点

  • 类声明不会被提升,与 let 和 const 一样,存在暂时性死区
  • 类中的所有代码均在严格模式下执行
  • 类的所有方法都是不可枚举的
  • 类的所有方法都无法被当作构造函数使用
  • 类的构造器必须使用 new 来调用

类的继承

如果两个类A和B,如果可以描述为:B 是 A,则A和B形成继承关系

  • B继承自A
  • A派生B
  • B是A的子类
  • A是B的父类
    • 如果A是B的父类,则B会自动拥有A中的所有实例成员。

新的关键字:

  • extends:继承,用于类的定义
  • super
    • 直接当作函数调用,表示父类构造函数
    • 如果当作对象使用,则表示父类的原型
class Animal {
  constructor(name, food) {
    this.name = name
    this.food = food
  }

  say() {
    return `我是${this.name}动物,吃的是${this.food}`
  }
}

class Dog extends Animal {
  constructor(name, food) {
    super(name)
    this.food = food
  }
}

const obj = new Dog('哈士奇', '肉肉')
console.log(obj.say()) // 我是哈士奇动物,吃的是肉肉

ES6要求,如果定义了constructor,并且该类是子类,则必须在constructor的第一行手动调用父类的构造函数
如果子类不写constructor,则会有默认的构造器,该构造器需要的参数和父类一致,并且自动调用父类构造器