之前的 JavaScript 沒有類的概念,它是基於原型的面相對象的語言。原型對象的特色就是將自身屬性共享給新對象。咱們先看一下下面的代碼實現。javascript
//常規寫法 function Person(name,age) { this.name = name; this.age = age; } Person.prototype.sayInfo = function () { console.log(`${this.name}是 ${this.age}歲`) } const liLei = new Person('LiLei',20) liLei.sayInfo() //LiLei是20歲
這種常規約定是以大寫字母開頭來表示一個構造器(大寫開頭非官方),能夠直接定義函數,也能夠經過 prototype 來擴展函數。這種實現跟 java 比,實現類的方案太特別了,下面咱們看一下 es6 的類的實現方式:前端
class Person{ //定義了一個名字爲Person的類 constructor(name,age){ //constructor是一個構造方法,用來接收參數 this.name = name; //this表明的是實例對象 this.age = age; } sayInfo(){ console.log(`${this.name}是 ${this.age}歲`) } } const liLei = new Person('LiLei',21) liLei.sayInfo()
由下面代碼能夠看出類實質上就是一個函數。類自身指向的就是構造函數。因此能夠認爲 ES6 中的類其實就是構造函數的另一種寫法!下面的代碼能夠證實這一點vue
console.log(typeof Person);//function console.log(Person===Person.prototype.constructor);//true
JavaScript 中的類一樣能夠像 java 同樣,能夠繼承某個類,其中被繼承的類稱爲父類,而繼承父類的被稱爲子類。子類能夠有本身的函數和構造器,當子類中存在父類相同的方法時,則該方法不會從父類繼承,而使用子類的方法。java
class Student { constructor(name){ this.name = name } sayName(){ console.log(this.name) } testFn(){ console.log('我是父類的函數!') } } class Worker extends Student{ sayWork(){ console.log(this.name) } testFn(){ console.log('我是子類的函數!') } } const person = new Worker('liLei') person.sayName() person.sayWork() person.testFn() //輸出: //liLei //liLei //我是子類的函數!
能夠看到子類 Worker 繼承了 Student 類的 sayName 函數和 name 這個內部變量。可是同名函數 testFn 沒有繼承,是調用到了子類的 testFn 函數。這裏也能夠理解爲子類的 testFn 函數覆蓋了父類的 testFn 函數。react
super 關鍵字的一個做用是用來訪問父類的構造器或者函數用的。子類在使用構造器的時候,必須使用 super 關鍵字,用來擴展構造器。上面提到的,子類同名函數會覆蓋父類同名函數,這時候,咱們使用 super 關鍵字,一樣能調用到父類的同名函數,就是簡單理解爲 super 實際上是父類的一個實例對象。git
class Student { constructor(name){ this.name = name } testFn(){ console.log('我是父類的函數!') } } class Worker extends Student{ constructor(name,age,sex){ super(name) //這裏必須先調用super,纔有下文的this對象,這裏擴展了一個變量age this.age = age this.sex = sex } testFn(){ super.testFn(); console.log("年齡" + this.age) console.log("性別" + this.sex) console.log('我是子類的函數!') } } const person = new Worker('liLei','20') person.testFn() //輸出: //我是父類的函數! //年齡20 //性別undefined //我是子類的函數! //我是子類的函數!
能夠看到上面用 super 關鍵字實現了子類的構造器,還擴展了 2 個變量 age,sex。同時使用 super 調用到了父類的方法,因此在子類中即便有父類的同名方法,同樣能夠實現父類同名方法的調用。super 能夠理解爲父類的一個會實例化對象,但不一樣的是 super 只能訪問父類的方法和,不能訪問私有變量。es6
static 關鍵字通常做用於類的方法,用來定義一個工具函數。static 方法不能被實例對象調用,只能經過類名來調用。同時 static 方法也能夠被繼承,並且也能在子類中用 super 對象來調用父類中的 static 方法。github
class Person{ //沒有constructor的類會默認生成一個constructor構造器 static sayName(){ console.log("我是static函數") } } class Student extends Person{} const student = new Student() Person.sayName() Student.sayName() student.sayName() //輸出: //我是static函數 //我是static函數 //student.sayName is not a function
能夠看到用實例化的對象來調用 static 方法時,代碼會報錯。框架
平時咱們開發的時候不多使用類的,特別是如今基於 vue 或者 react 開發時,一些組件化的東西直接使用各自框架封裝好的方式引用,就使用的更少了。
可是某些時候,咱們使用 es6 的類可讓咱們的代碼的可讀性更高。好比說一個分頁組件,裏面會有計算總頁數,上一頁,下一頁,跳頁等方法。咱們能夠把這個分頁函數寫在一個類裏面,在引用的地方去實例化它,當一個頁面有多個分頁時,也能夠實例化多個,獨立調用,互不影響。
總結來講,類能夠在封裝工具的時候用。最後附上分頁工具類的大體代碼:函數
class PageUtil{ constructor(pageNo,pageSize,total){ //構造初始變量 this.pageNo = pageNo; //起始頁面 this.pageSize = pageSize //一頁數據條數 this.total = total //數據總數 this.currentPage = 0 //當前選中頁數 this.pageTotal = Math.ceil(this.total/this.pageSize) //總頁數 } nextPage(){ //下一頁 if(this.currentPage < this.pageTotal){ this.currentPage++ } } beforePage(){ //上一頁 if(this.currentPage > 1){ this.currentPage-- } } jumpPage(page){ //跳頁 this.currentPage = page } changePageSize(pageSize){ //改變頁大小 this.pageSize = pageSize this.pageTotal = Math.ceil(this.total/this.pageSize) //總頁數 } getTotalPage(){ //獲取總頁數 return Math.ceil(this.total/this.pageSize) } } class DialogPage extends PageUtil{ //繼承PageUtil類 constructor(pageNo,pageSize,total,pageTotal){ super(pageNo,pageSize,total) this.pageTotal = pageTotal } getTotalPage(){ return this.pageTotal || super.getTotalPage() //重寫getTotalPage方法 } } const contentPage = new PageUtil(1,10,100) //實例化2個pageUtil對象 contentPage.getTotalPage() const dialogPage = new DialogPage(1,10,100,10) dialogPage.getTotalPage()
全部的源碼均可以在個人倉庫地址:https://github.com/jackzhujie...
學習如逆水行舟,不進則退,前端技術飛速發展,若是天天不堅持學習,就會跟不上,我會陪着你們,天天堅持推送博文,跟你們一同進步,但願你們能關注我,第一時間收到最新文章。
公衆號: