前言
記得之前有一次面試,面試官問我,有幾種面對對象的設計方式。
我一下懵了,雖然高級程序設計的第六章我看了好多遍,但確實太久沒有用了,如果沒有準備面試是對面試官的不尊重,我確實有點失禮了。
有些人說,es6,沒有必要記那么多種復雜的類的實現方式了。
我偏向于這種說法,prototype單詞實在太長,而且類的實現方式隱晦難懂。
示例
/*
* class是關鍵字
* className是函數名稱
* constructor函數等同于之前的函數constructor
* name 是往這個class傳入的參數
* sayName 是給函數prototype上添加的方法
*/
class className {
constructor(name){
this.name = name;
}
sayName(){
console.log(this.name);
}
}
為什么用class方法
- 不會變量提升,class聲明類似于let聲明
- 函數內部的方法內部自動使用strict mode
- 里面定義的所有方法都不可枚舉
- 所有的方法內部都有一個都有一個內部的[[Construct]]方法,如果new調用,會報錯
- 在class內部試圖重寫class名會報錯
使用方法
類可以作為參數傳入函數
類可以立即執行
//類表達式
let PersonClass1 = class {/*內部代碼省略*/};
//命名的類表達式
let PersonClass2 = class PersonClass22 {/*內部代碼省略*/};
類內部方法的設定
get
class a {
get methodName(){
}
}
set
class a {
set methodName(){
}
}
生成器方法
class a{
*createIterator(){
yield 1;
}
}
static 靜態方法
class a {
static methodName(){
}
}
//static關鍵字不能用于constructor方法
//無法獲取實例屬性,簡單的說,就是this底下的值
方法名稱可以是變量
let method = 'methodName'
let PersonClass = class {
[method] (){
//do something
}
}
類的繼承
示例
//使用extends關鍵字
//可以用super()來調用父類的constructor
//如果在子類無constructor(),則自動調用父類的super()
class Child extends Parent{
//無constructor
}
//下例和上例相同
class Child extends Parend{
constructor(args){
super(...args);
}
}
super()
- 只能在繼承關系的子類使用super()
- 必須調用super(),來初始化this
- 惟一避免調用super(),是從class的constructor()中返回一個對象
備注
- 可以在子類中屏蔽父類的方法
- 可以通過繼承靜態方法
- 可以從ES5寫法的類中繼承,只要父類有[[Constructor]]和prototype
- 可以從內建對象中繼承
Symbol.species 屬性
繼承自內建對象,子類使用任何父類的方法,都會返回子類的實例
下列內建對象中有Symbol.species
- Array
- ArrayBuffer
- Map
- Promise
- RegExp
- Set
- Typed arrays
new.target
只可在類的constructor內使用。
在繼承時,子類調用父類, new.target 不等于父類名稱。
可以通過這個性質,阻止其他方法繼承這個類。