class 本质上来说,是 JS 类实现的一个语法糖,很多行为和 ES5 使用 function 关键字声明一个类是一致的。ES5 使用 function 关键字作为构造函数的时候,主要是利用 function 身上的 prototype 属性来实现继承的,而通过 class 关键字声明一个类也是通过 prototype 属性来实现继承的,使用 class 关键字声明一个类会让原型的写法更加清晰,更符合面向对象编程语言的风格。
一些相同的地方
- 都可以使用 extends 关键字实现继承,都可以继承静态方法
但也有一些不同的地方
使用 class 和 function 关键字声明类的不同
- class 声明的类必须使用 new,否则会报错。
- class 内部定义的原型方法是不可枚举的,而使用 function 关键字定义的原型方法是可枚举的。所谓可枚举就是可以通过 for...in 循环、Object.keys()等方法可以遍历出来。
- class 内部默认是严格模式
- class 不存在变量提升
- class中定义在prototype上的方法不能使用new来调用
将类转为普通构造函数的写法
js
class Example{
constructor(name){
this.name = name
}
func(){
console.log(this.name)
}
}转为普通构造函数后
js
// 严格模式
'use strict'
function Example(name) {
// 是否使用new关键字来调用
if (!new.target) {
throw new TypeError(
`Class constructor Example cannot be invoked without 'new'`
)
}
this.name = name
}
Object.defineProperty(Example.prototype, 'func', {
value: function () {
if (new.target) {
throw new TypeError('Example.prototype.func is not a constructor')
}
console.log(this.name)
},
enumerable: false,
})
// 必须使用new关键字来调用
// Example()
// 不可遍历
// const e = new Example()
// for (const key in e) {
// console.log(key)
// }
// Example.prototype上的方法不能使用new来调用
// new Example.prototype.func()