听说你对 ES6 class 类还不是很了解
大家好,我是若川。最近組織了源碼共讀活動,感興趣的可以加我微信?ruochuan12?參與。
前言
在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?=?18class?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?functionstatic
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類中是不支持的。
報錯.pngpublic
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?=?nullconstructor()?{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文章感興趣的小伙伴可以點個關注+贊哦。
最近組建了一個江西人的前端交流群,如果你是江西人可以加我微信?ruochuan12?私信 江西 拉你進群。
推薦閱讀
1個月,200+人,一起讀了4周源碼
我歷時3年才寫了10余篇源碼文章,但收獲了100w+閱讀
老姚淺談:怎么學JavaScript?
我在阿里招前端,該怎么幫你(可進面試群)
·················?若川簡介?·················
你好,我是若川,畢業于江西高校。現在是一名前端開發“工程師”。寫有《學習源碼整體架構系列》10余篇,在知乎、掘金收獲超百萬閱讀。
從2014年起,每年都會寫一篇年度總結,已經寫了7篇,點擊查看年度總結。
同時,最近組織了源碼共讀活動,幫助1000+前端人學會看源碼。公眾號愿景:幫助5年內前端人走向前列。
識別上方二維碼加我微信、拉你進源碼共讀群
今日話題
略。歡迎分享、收藏、點贊、在看我的公眾號文章~
總結
以上是生活随笔為你收集整理的听说你对 ES6 class 类还不是很了解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 前端学习(2991):vue+eleme
- 下一篇: SD卡格式化咋办?数据恢复看这里!