(Day 21) ES6 class 語法糖
前言
前面有花幾篇介紹了,原型鍊以及使用建構式、以及使用 Object.create()
建立多層原型。
一邊介紹也會發現原型寫法,容易有不好閱讀的問題,例如:
- 函式建構式容易和一般函式搞混。
- 函式建構式只能新增的實體,若要新增方法,需在在函式建構式的原型上新增方法。
- 多層原型時需另外使用
Object.create()
將子層、父層的原型串起來。
整體來說就是閱讀上不夠直覺,原型相關語法讓人感覺是拼拼湊湊組合出來,因此 JavaScript 在 ES6 時,有新增了原型的語法糖class
,雖然整個概念和原本寫法一樣,但是用class
建立的原型確實更容易理解也更容易閱讀。
使用 class 建立原型
以上次衣服範例:
1
2
3
4
5
6
7
8
9
10
11function TShirt(color,material,size){
this.color = color
this.material = material
this.size = size
}
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')class
語法糖寫成就會是:
1
2
3
4
5
6
7
8
9
10
11
12class TShirt {
constructor (color,material,size) {
this.color = color
this.material = material
this.size = size
}
clothe(){
console.log(`穿上 ${this.color} T Shit`);
}
}
const BlackTShit = new TShirt('black','棉','L')
從範例可以發現,class
語法糖最大特色是所有原型設定,都會寫到class
中,constructor()
就是用來設定原本的函式建構式,而原型方法則是直接新增在 class 底下,相當直覺。
在來看看使用Object.create()
建立多層原型,以及class
建立多層原型的對比,在開始寫範例之前,要先介紹class
會使用到的兩個新方法extends
、super
。
extends
: 繼承於另一個原型之下super
: 使用上層的值(屬性)
原始寫法:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23function apparel(type){
this.type = type || '帽 T'
}
apparel.prototype.mirror = function(){
console.log(`我穿著 ${this.color} 的 ${this.type} `)
}
function TShirt(color,material,size){
apparel.call(this, 'T Shirt')
this.color = color
this.material = material
this.size = size
}
TShirt.prototype = Object.create(apparel.prototype)
TShirt.prototype.constructor = TShirt
TShirt.prototype.clothe = function() {
console.log(`穿上 ${this.color} T Shit`);
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.mirror() // 我穿著 black 的 T Shirt
BlackTShit.clothe() //穿上 black T Shit
class 版本:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25class apparel {
constructor (type){
this.type = type || '帽 T'
}
mirror(){
console.log(`我穿著 ${this.color} 的 ${this.type} `)
}
}
// 使用 extends 讓 TShirt 原型繼承 apparel
class TShirt extends apparel {
constructor(color,material,size) {
super('T Shit') // 使用 super() 讓 TShirt 原型能使用上一層的 apparel 的 type 屬性
this.color = color
this.material = material
this.size = size
}
clothe(){
console.log(`穿上 ${this.color} T Shit`);
}
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.mirror() // 我穿著 black 的 T Shirt
BlackTShit.clothe() //穿上 black T Shit
從以上範例可以看的出來,即變使用多層建立的方法,也可以發現class
的原型設定都是在class
方法內,因此比起原本的原型設定,使用class
寫法,對開發者來說是友善許多。
最後來說說兩個在 class 中新增的特有方法
- static 靜態方法
- Setter, Getter
static 靜態方法
若要使用static
需在 class 的方法名稱前添加static
,設置了static
的方法,只能夠讓原型使用,一般實體資料是無法使用。
1
2
3
4
5
6
7
8
9
10
11
12
13
14class TShirt {
constructor (color,material,size) {
this.color = color
this.material = material
this.size = size
}
static clothe(){
console.log(`穿上 ${this.color} T Shit`);
}
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.clothe() // BlackTShit.clothe is not a function
TShirt.clothe() // 穿上 undefined T ShitSetter, Getter
和static
一樣若要使用 Setter ﹑ Getter ,需要將set
、get
寫在 class 的方法前,而這兩個方法從名稱便可得知是功能是傳入以及傳出。
set
傳入資料,可以透過set
方法修改原型中的資料,要注意的是這邊使用的不是呼叫函式的()
,而是使用=
運算子提供資料,因此一次只能傳送一個值。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18class TShirt {
constructor(color, material, size) {
this.color = color
this.material = material
this.size = size
}
set chageColor(color) {
this.color = color
}
clothe() {
console.log(`穿上 ${this.color} T Shit`);
}
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.clothe() // 穿上 black T Shit
BlackTShit.chageColor = 'Red'
BlackTShit.clothe() // 穿上 Red T Shit- 使用
get
可以獲得原型中的資料,和set
方法一樣,get
方法不會使用到()
1
2
3
4
5
6
7
8
9
10
11
12
13class TShirt {
constructor (color,material,size) {
this.color = color
this.material = material
this.size = size
}
get getColor(){
return this.color;
}
}
const BlackTShit = new TShirt('black','棉','L')
BlackTShit.getColor // 'black'參考文獻
- JavaScript 核心篇 (六角學院)