在es5中主要是通過(guò)構(gòu)造函數(shù)方式和原型方式來(lái)定義一個(gè)類,在es6中我們可以通過(guò)class來(lái)定義類,今天整理一下它們的區(qū)別。
關(guān)于es5中定義類的方式,可以看這一篇Js的‘類’,我們這里主要聊es5類和es6中class類的區(qū)別。
一、class類必須new調(diào)用,不能直接執(zhí)行。
image
class類執(zhí)行的話會(huì)報(bào)錯(cuò),而es5中的類和普通函數(shù)并沒(méi)有本質(zhì)區(qū)別,執(zhí)行肯定是ok的。
二、class類不存在變量提升
image
image
圖2報(bào)錯(cuò),說(shuō)明class方式?jīng)]有把類的定義提升到頂部。
三、class類無(wú)法遍歷它實(shí)例原型鏈上的屬性和方法
function Foo (color) {
this.color = color
}
Foo.prototype.like = function () {
console.log(`like${this.color}`)
}
let foo = new Foo()
for (let key in foo) {
// 原型上的like也被打印出來(lái)了
console.log(key) // color、like
}
class Foo {
constructor (color) {
this.color = color
}
like () {
console.log(`like${this.color}`)
}
}
let foo = new Foo('red')
for (let key in foo) {
// 只打印一個(gè)color,沒(méi)有打印原型鏈上的like
console.log(key) // color
}
四、new.target屬性
es6為new命令引入了一個(gè)new.target屬性,它會(huì)返回new命令作用于的那個(gè)構(gòu)造函數(shù)。如果不是通過(guò)new調(diào)用或Reflect.construct()調(diào)用的,new.target會(huì)返回undefined
function Person(name) {
if (new.target === Person) {
this.name = name;
} else {
throw new Error('必須使用 new 命令生成實(shí)例');
}
}
let obj = {}
Person.call(obj, 'red') // 此時(shí)使用非new的調(diào)用方式就會(huì)報(bào)錯(cuò)
五、class類有static靜態(tài)方法
static靜態(tài)方法只能通過(guò)類調(diào)用,不會(huì)出現(xiàn)在實(shí)例上;另外如果靜態(tài)方法包含 this 關(guān)鍵字,這個(gè) this 指的是類,而不是實(shí)例。static聲明的靜態(tài)屬性和方法都可以被子類繼承。
class Foo {
static bar() {
this.baz(); // 此處的this指向類
}
static baz() {
console.log('hello'); // 不會(huì)出現(xiàn)在實(shí)例中
}
baz() {
console.log('world');
}
}
Foo.bar() // hello