Class 重點筆記
關於 Class
class
就是構造函數的語法糖,也可以說是構造函數的另一種寫法,使用時直接對 class
調用 new
即可:
class C1 {
constructor(lastName, firstName) {
this.lastName = lastName;
this.firstName = firstName;
}
logName() {
console.log(`My name is ${this.lastName} ${this.firstName}`);
}
}
let c1 = new C1('Peng', 'Jing Jun');
c1.logName(); // My name is Peng Jing Jun
第一次學習 class
時雖然聽過它是構造函數的語法糖,但其實乍看之下還是挺不直覺的,所以這邊解剖一下上述代碼做了些什麼:
首先聲明了一個
C1
的class
,換成構造函數的寫法就是function C1 () {};
class
內定義的方法最終都位於原型上,換成構造函數的寫法就是C1.prototype.logName = function () {};
constructor
方法就是構造函數,內部的this
指向被new
出來的實體constructor
是class
的默認方法,通過new
關鍵字生成的實體會自動調用constructor
方法,即使沒有定義constructor
也會默認產生一個空的constructor
console.log(typeof C1); // function
console.log(C1 === C1.prototype.constructor); // true
構造函數的語法糖 class
只是讓原型的寫法更清晰、更像物件導向的語法而已
上述代碼說明了 class
的型別就是函數,而 class
本身就是指向構造函數
注意事項:
class
內部定義的方法皆不可枚舉constructor
方法默認返回實體物件class
與module
內部默認以嚴格模式運行,所以不需要再使用use strict
class
內部不存在hoisting
class
的方法如果內部含有this
則默認指向class
實體
靜態方法
所有在 class
中定義的方法都會被實體繼承,如果不希望被繼承的話,在方法名前加上 static
關鍵字就表示該方法不會被實體繼承,而且直接通過 class
就可以調用:
class C1 {
static helloWorld() {
console.log('Hello World!');
}
}
C1.helloWorld(); // Hello World!
const c1 = new C1();
c1.helloWorld(); // c1.helloWorld is not a function
上面說明了靜態方法可以直接於 class
上調用,而不是在 class
的實體上調用,如果在實體上調用的話就會噴錯,表示該方法並不存在
另外,父類別的靜態方法可以被子類別繼承:
繼承
JavaScript 類別使用 extends
關鍵字實現單繼承:
class Father {
name;
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Child extends Father {
hello = 'Hello';
}
const res = new Child('Allen Iverson');
console.log(res.name); // Allen Iverson
console.log(res.getName()); // Allen Iverson
console.log(res.hello); // Hello
這段代碼 class Child extends Father {}
使得 Child
繼承 Father
的字段、方法以及構造函數
父類別的構造函數:constructor()
中的 super()
如果想在子類別中調用父類別的構造函數,需要在子類別的構造函數中使用 super()
方法:
class Father {
name;
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Child extends Father {
hello = 'Hello';
constructor(name, str) {
super(name);
this.hello = str;
}
}
const res = new Child('Allen Iverson', 'Changed');
console.log(res.name); // Allen Iverson
console.log(res.getName()); // Allen Iverson
console.log(res.hello); // Changed
上述代碼中在子類別 Child
中的 super(name)
執行了父類別 Father
的構造函數
另外,在子類別構造函數中必須在使用 this
關鍵字之前調用 super()
方法,這樣才能確保父類別的構造函數完成初始化:
class Child extends Father {
hello = 'Hello';
constructor(name, str) {
// ReferenceError ...
this.hello = str;
super(name);
}
}
父類別實體:方法中的 super
class Father {
name;
constructor(name) {
this.name = name;
}
getName() {
return this.name;
}
}
class Child extends Father {
constructor(name) {
super(name);
}
getName() {
const name = super.getName();
if (name === '') {
console.log('Empty');
} else {
console.log(name);
}
}
}
const res = new Child('');
res.getName(); // Empty
上述代碼中子類別 Child
中的 getName()
透過 super
訪問了父類別 Father
的方法 getName()
另外,也可以在靜態方法中使用 super
訪問父類別的靜態方法