聽說你對 ES6 class 類還不是很瞭解
前言
在ES5
中是原型函數,到了ES6
中出現了 "類" 的概念。等同於是ES5
的語法糖,大大提升了編寫代碼的速度,本文只講一些常用的(其實也就那幾個屬性),下面就讓我們來認識一下類
吧
基本使用
定義類
的關鍵字就是class
,下面這樣就是定義了一個類
,跟我們ES5
構造函數一樣,都是使用new
關鍵字
class Person {
}
const cateory = new Person() // 調用 類
類繼承
在ES5
中,我們要繼承的話得使用call
或者prototype
來繼承原型或者實例上的方法,但是在ES6
中爲我們提供了extends
關鍵字直接使用就好,同樣它會繼承方法
和屬性
class Person {
name = "前端娛樂圈";
hello() {
return "你好"
}
}
class Scholl extends Person {
getName() {
return this.name;
}
}
const res = new Scholl();
console.log(res.getName()) // 前端娛樂圈
console.log(res.hello()) // 你好
constructor
constructor
構造函數,它就是當前實例的構造函數。每一個類裏面只能存在一個constructor
,當類
實例化的時候(也就是 new)constructor
會立即執行。如果一個類
裏面沒有顯示定義constructor
構造函數的話,會默認隱式被添加進類
中並且返回值是當前類
,當然也可以顯示手動return
返回其它引用值,這時當前的實例就是constructor
的返回值。
// 默認不寫
class Person {
}
console.log(new Person()) // 默認constructor指向自己的實例
// 顯示寫上constructor
class Person1 {
constructor() {
}
}
console.log(new Person1()) // 顯示地寫上constructor構造函數。實例對象返回當前的constructor
// 顯示的返回對象
class Person2 {
constructor() {
return {}
}
}
console.log(new Person2()) // 這實例的返回值就是一個空對象,constructor返回值只有是對象纔可以
super 關鍵字
class Person {
}
class school extends Person {
constructor() {
super() // 這裏繼承了Person類,但是必須使用super調用,否則會報錯。
}
}
上面school
類繼承了Person
類,如果不在constructor
中調用super
關鍵字那麼它就會報錯。因爲子類沒有自己的this
對象,而是繼承父類的this
對象,這裏的super
關鍵字就是父類Person
對象。最終實例化返回的是school
實例,super
函數 內部會Person.prorotype.constructor.call(this)
注意,super 函數只能在類中執行一次,否則會報錯
super 關鍵字也可以當做一個對象使用
class Person {
getName() {
return "前端娛樂圈"
}
}
Person.prototype.name = "蛙人"
Perosn.prototype.age = 18
class school extends Person {
constructor() {
const res = super() // 這裏的super指向Person類
console.log(super.getName(), super.name) // 這裏的super關鍵字指向Person.prototype
}
getAge() {
console.log(super.age)
}
}
上面代碼中,super
函數只能擁有一個,但super
關鍵字可以當成一個對象使用,super
關鍵字當成對象指向的是父類prototype
原型對象。super
關鍵字可以在類的任何地方使用,但super
函數只能在constructor
中使用。
注意:super 函數返回值是當前類的實例,super 關鍵字指向的當前類的 prototype
get
用於獲取取值屬性,剛在上面我們說過,私有屬性不能在類的外部訪問,但是我們可以通過get
關鍵字來獲取類裏面的私有屬性。
class Person {
private username = "前端娛樂圈";
private age = 18;
get getVal() {
return this.username;
}
}
const res = new Person();
console.log(res.getVal) // 前端娛樂圈
那麼我們來看一下,這個get
關鍵字和定義一個方法有何不同。
class Person {
private username = "前端娛樂圈";
private age = 18;
getVal() {
return this.username;
}
}
const res = new Person();
console.log(res.getVal()) // 前端娛樂圈
上面我們把get
關鍵字去掉了,並且調用時候的帶上了()
代表要執行一個函數。雖然這樣寫跟get
關鍵字效果是一樣的,但是不推薦我們這麼寫,就像Vue
中我們使用computed
寫,就不推薦methods
裏面寫。官方定義的get
是取值函數,我們取值直接用get
關鍵字就行也不用寫()
,就像獲取一個屬性一樣。
set
set
存值函數,上面說了get
,那麼有get
就一定有set
。存值函數跟取值函數一個意思,一個獲取一個設置嘛。
class Person {
private username = "前端娛樂圈";
private age = 18;
get getVal() {
return this.username;
}
set setVal(val) {
this.username = val
}
}
const res = new Person();
res.setVal = "蛙人"
console.log(res.getVal()) // 蛙人
上面我們先執行了存值,然後在取值,跟我們預期的結果一樣,我們存值改變了username
,獲取值也會改變。
私有屬性
在類中私有屬性必須以#
開頭聲明,以#
開頭的只能在類中訪問,在類的外部不能訪問。如果用的TypeScript
完全可以使用private
代替。
class Person {
#name = "蛙人"
constructor() {
}
getName() {
return this.#name
}
#getAge() {
return 18
}
}
const res = new Person();
// console.log(this.#name) // 報錯,必須在封閉類中聲明該字段
console.log(res.getName()) // 蛙人
console.log(res.#getAge) // 報錯,getAge is not function
static
static
爲類
的靜態屬性,"靜態數據" 是啥意思呢,就是不用實例化類
就可以訪問的屬性。像我們不是static
定義的屬性和方法都必須的實例化類才能調用。
這裏需要注意一下,當我們定義完
非 static 定義的屬性
class Person {
username = "前端娛樂圈";
age = 18;
}
const res = new Person().username; // 前端娛樂圈
像我們這種非static
定義的屬性,要想訪問username
屬性就必須得實例化new
才能訪問。
static 定義的屬性
static
定義的靜態屬性,就是不用實例化就可以直接訪問。不定義在實例化對象上面。
// 之前老的寫法
class Person {}
Person.username = "前端娛樂圈"
// 新寫法,加一個static關鍵字即可
class Person {
static username = "前端娛樂圈";
static age = 18;
static getName() {
return Person.username
}
}
console.log(Person123.username, Person123.getName()) // 前端娛樂圈,前端娛樂圈
之前老寫法的靜態屬性定義在類的外部。整個類生成以後,再生成靜態屬性。這樣讓人很容易忽略這個靜態屬性,也不符合相關代碼應該放在一起的代碼組織原則。爲了解決這問題,就新出的static
關鍵字靜態方法
以下這三個修飾符是在
TypeScript
類中才能使用,在JavaScript
類中是不支持的。
報錯. png
public
public
爲類
的公共屬性,就是不管在類
的內部還是外部,都可以訪問該類
中屬性及方法。默認定義的屬性及方法都是public
。
class Person {
name = "前端娛樂圈";
public age = 18;
}
const res = new Person();
console.log(res.name, res.age) // 前端娛樂圈 18
上面可以看到打印結果都能顯示出來,name
屬性沒有定義public
公共屬性,所以類
裏面定義的屬性及方法默認都是public
定義。
private
private
爲類
的私有屬性,只有在當前類
裏面才能訪問,當前類
就是{}
裏面區域內。在{}
外面是不能訪問private
定義的屬性及方法的
class Person {
private name = "前端娛樂圈";
private age = 18;
}
const res = new Person();
console.log(res.name, res.age) // 這倆行會爆紅,當前屬性爲私有屬性,只能在類內部訪問
class Scholl extends Person {
getData() {
return this.username + "," + this.age
}
}
const temp = new Scholl()
console.log(temp.getData()) // 爆紅~,雖然繼承了Person類,但是private定義是隻能在當前類訪問,子類也不能訪問。
protected
protected
爲類
的保護屬性,只有在當前類和子類可以訪問。也就是說用protected
屬性定義的子類也可以訪問。
class Person {
protected username = "前端娛樂圈";
protected age = 18;
}
const res = new Person();
console.log(res.name, res.age) // 這倆行會爆紅,當前屬性爲私有屬性,只能在類內部訪問
class Scholl extends Person {
getData() {
return this.username + "," + this.age
}
}
const temp = new Scholl()
console.log(temp.getData()) // 前端娛樂圈,18。可以正常訪問父類的屬性
例子
例如我們寫如下一個小Demo
彈窗,可以單獨寫一個class類
裏面,這樣寫法是不是比我們ES5
中的prototype
寫法看着舒服多了。當然我們日常開發中的業務,公共方法也可以寫進一個類
裏面
class Mask {
isShow = false;
elem = null
constructor() {
this.elem = this.init()
}
init() {
const oDiv = document.createElement("div");
document.body.appendChild(oDiv);
return oDiv;
}
show() {
this.elem.style.display = "block"
this.isShow = true;
}
hide() {
this.elem.style.display = "none"
this.isShow = false;
}
}
結語
ES6
的class類
畢竟是一個 “語法糖”,所以只要理解了JavaScript
中對象的概念和麪向對象的思想,class
就不難理解啦~,下篇準備更新TypeScript文章
感興趣的小夥伴可以點個關注 + 贊哦。
本文由 Readfog 進行 AMP 轉碼,版權歸原作者所有。
來源:https://mp.weixin.qq.com/s/JgqCZooaNo6jfM3yHLi1EQ