(Day 21) ES6 class 语法糖

前言

前面有花几篇介绍了,原型链以及使用建构式、以及使用 Object.create() 建立多层原型。

一边介绍也会发现原型写法,容易有不好阅读的问题,例如:

  • 函式建构式容易和一般函式搞混。
  • 函式建构式只能新增的实体,若要新增方法,需在在函式建构式的原型上新增方法。
  • 多层原型时需另外使用 Object.create() 将子层、父层的原型串起来。

整体来说就是阅读上不够直觉,原型相关语法让人感觉是拼拼凑凑组合出来,因此 JavaScript 在 ES6 时,有新增了原型的语法糖 class,虽然整个概念和原本写法一样,但是用 class 建立的原型确实更容易理解也更容易阅读。

使用 class 建立原型

以上次衣服范例:

function 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 语法糖写成就会是:

class 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 会使用到的两个新方法 extendssuper

  • extends : 继承於另一个原型之下
  • super : 使用上层的值(属性)

原始写法:

function 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 版本:

class 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 的方法,只能够让原型使用,一般实体资料是无法使用。

class 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 Shit

Setter, Getter

static 一样若要使用 Setter ﹑ Getter ,需要将 setget 写在 class 的方法前,而这两个方法从名称便可得知是功能是传入以及传出。

  • set 传入资料,可以透过 set 方法修改原型中的资料,要注意的是这边使用的不是呼叫函式的 () ,而是使用 = 运算子提供资料,因此一次只能传送一个值。
class 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 方法不会使用到 ()
class 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 核心篇 (六角学院)

<<:  [DAY 06] 盐水爱河 春天小栈

>>:  第 05 天 多加尝试突破自我( leetcode 100 )

IEEE-754 与浮点数运算

本文目标 IEEE-754 规范对於工程发展的重要性 认识浮点数 使用演算法改善浮点数运算时带来的误...

Day 7:225. Implement Stack using Queues

今日题目 题目连结:225. Implement Stack using Queues 题目主题:S...

[Day 12] 切版就从布局开始 Application

要做这种SPA网页,最底层的布局就很重要了,这篇主要会介绍Vuetify布局的方式 布局范例 先来看...

Day 12 - var 、let、const

var 为全域变数,超不谨慎,宣告变数後值可被改变,也可以重复宣告。 let 为区域变数,较谨慎,...

Day 29 - 台湾5G发展元年的科普书阅读笔记

行动5.0:创造5G数位红利 5G来了! 5G大奇航-迎向下世代行动宽频的极致用户体验 这几个月来...