ES6 class類的用法

伊澤瑞爾發表於2019-02-27
es6 class基礎用法

以前的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中的類其實就是建構函式的另外一種寫法!下面的程式碼可以證明這一點

console.log(typeof Person);//function
console.log(Person===Person.prototype.constructor);//true
複製程式碼
類的繼承

JavaScript中的類同樣可以像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函式。

super關鍵字的使用

super關鍵字的一個作用是用來訪問父類的構造器或者函式用的。子類在使用構造器的時候,必須使用super關鍵字,用來擴充套件構造器。上面提到的,子類同名函式會覆蓋父類同名函式,這時候,我們使用super關鍵字,同樣能呼叫到父類的同名函式,就是簡單理解為super其實是父類的一個例項物件。

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只能訪問父類的方法和,不能訪問私有變數。

static關鍵字

static關鍵字一般作用於類的方法,用來定義一個工具函式。static方法不能被例項物件呼叫,只能通過類名來呼叫。同時static方法也可以被繼承,而且也能在子類中用super物件來呼叫父類中的static方法。

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方法時,程式碼會報錯。

es6中類的使用場景

平時我們開發的時候很少使用類的,特別是現在基於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()
複製程式碼

全文完,如果有不對的地方,希望能積極指出來,大家都是學習者。

相關文章