传统构造函数出现的问题
- 属性和原型方法定义分离,降低了可读性
- 原型成员可以被枚举
- 默认情况下,构造函数仍然可以被当作普通函数使用
概述
在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,则会有默认的构造器,该构造器需要的参数和父类一致,并且自动调用父类构造器