class類是es6語(yǔ)法,是es6新增的一種特性。ES6中,引入了class關(guān)鍵字用于快速地定義“類”,但是類的本質(zhì)是function;它可以看作一個(gè)語(yǔ)法糖,讓對(duì)象原型的寫(xiě)法更加清晰、更像面向?qū)ο缶幊痰恼Z(yǔ)法。用class定義類的方法“class Person{//類聲明}”或“const Person=class{//類表達(dá)式}”。
前端(vue)入門到精通課程:進(jìn)入學(xué)習(xí)
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點(diǎn)擊使用
本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。
class類是es6語(yǔ)法,是es6新增的一種特性。
ES6中,引入了class關(guān)鍵字用于快速地定義“類”。
在JS中,“類”的本質(zhì)是function,可以將其看做一個(gè)語(yǔ)法糖,讓對(duì)象原型的寫(xiě)法更簡(jiǎn)潔清晰,更像面向?qū)ο缶幊痰恼Z(yǔ)法。
認(rèn)識(shí)class定義類
我們會(huì)發(fā)現(xiàn),按照前面的構(gòu)造函數(shù)形式創(chuàng)建 類,不僅僅和編寫(xiě)普通的函數(shù)過(guò)于相似,而且代碼并不容易理解。
在ES6(ECMAScript2015)新的標(biāo)準(zhǔn)中使用了class關(guān)鍵字來(lái)直接定義類;但是類本質(zhì)上依然是前面所講的構(gòu)造函數(shù)、原型鏈的語(yǔ)法糖而已;所以學(xué)好了前面的構(gòu)造函數(shù)、原型鏈更有利于我們理解類的概念和繼承關(guān)系;
那么,如何使用class來(lái)定義一個(gè)類呢?–可以使用兩種方式來(lái)聲明類:類聲明和類表達(dá)式;
class Person{ //類聲明 } const Person=class{ //類表達(dá)式 }
類和構(gòu)造函數(shù)的異同
我們來(lái)研究一下類的一些特性:你會(huì)發(fā)現(xiàn)它和我們的構(gòu)造函數(shù)的特性其實(shí)是一致的;
console.log(Person.prototype) console.log(Person.prototype.__proto__)//Object null console.log(Person.prototype.constructor)//Person console.log(typeof Person) // function var p = new Person() console.log(p.__proto__ === Person.prototype) // true
類的構(gòu)造函數(shù)
如果我們希望在創(chuàng)建對(duì)象的時(shí)候給類傳遞一些參數(shù),這個(gè)時(shí)候應(yīng)該如何做呢?
- 每個(gè)類都可以有一個(gè)自己的構(gòu)造函數(shù)(方法),這個(gè)方法的名稱是固定的constructor;
- 當(dāng)我們通過(guò)new操作符,操作一個(gè)類的時(shí)候會(huì)調(diào)用這個(gè)類的構(gòu)造函數(shù)constructor;
- 每個(gè)類只能有一個(gè)構(gòu)造函數(shù),如果包含多個(gè)構(gòu)造函數(shù),那么會(huì)拋出異常;
當(dāng)我們通過(guò)new關(guān)鍵字操作類的時(shí)候,會(huì)調(diào)用這個(gè)constructor函數(shù),并且執(zhí)行如下操作:
- 1.在內(nèi)存中創(chuàng)建一個(gè)新的對(duì)象(空對(duì)象);
- 2.這個(gè)對(duì)象內(nèi)部的[[prototype]]屬性會(huì)被賦值為該類的prototype屬性;
- 3.構(gòu)造函數(shù)內(nèi)部的this,會(huì)指向創(chuàng)建出來(lái)的新對(duì)象;
- 4.執(zhí)行構(gòu)造函數(shù)的內(nèi)部代碼(函數(shù)體代碼);
- 5.如果構(gòu)造函數(shù)沒(méi)有返回非空對(duì)象,則返回創(chuàng)建出來(lái)的新對(duì)象;
類的實(shí)例方法
在上面我們定義的屬性都是直接放到了this上,也就意味著它是放到了創(chuàng)建出來(lái)的新對(duì)象中:
在前面我們說(shuō)過(guò)對(duì)于實(shí)例的方法,我們是希望放到原型上的,這樣可以被多個(gè)實(shí)例來(lái)共享;
這個(gè)時(shí)候我們可以直接在類中定義;
class Person { constructor(name, age) { this.name = name this.age = age this._address = "廣州市" } // 普通的實(shí)例方法 // 創(chuàng)建出來(lái)的對(duì)象進(jìn)行訪問(wèn) // var p = new Person() // p.eating() eating() { console.log(this.name + " eating~") } running() { console.log(this.name + " running~") } }
類的訪問(wèn)器方法
我們之前講對(duì)象的屬性描述符時(shí)有講過(guò)對(duì)象可以添加setter和getter函數(shù)的,那么類也是可以的:
class Person { constructor(name, age) { this.name = name this.age = age this._address = "廣州市" } // 類的訪問(wèn)器方法 get address() { console.log("攔截訪問(wèn)操作") return this._address } set address(newAddress) { console.log("攔截設(shè)置操作") this._address = newAddress } }
類的靜態(tài)方法
靜態(tài)方法通常用于定義直接使用類來(lái)執(zhí)行的方法,不需要有類的實(shí)例,使用static關(guān)鍵字來(lái)定義:
class Person { constructor(name, age) { this.name = name this.age = age this._address = "廣州市" } // 類的靜態(tài)方法(類方法) // Person.createPerson() static randomPerson() { var nameIndex = Math.floor(Math.random() * names.length) var name = names[nameIndex] var age = Math.floor(Math.random() * 100) return new Person(name, age) } }
ES6類的繼承 – extends
前面我們花了很大的篇幅討論了在ES5中實(shí)現(xiàn)繼承的方案,雖然最終實(shí)現(xiàn)了相對(duì)滿意的繼承機(jī)制,但是過(guò)程卻依然是非常繁瑣的。在ES6中新增了使用extends關(guān)鍵字,可以方便的幫助我們實(shí)現(xiàn)繼承:
class Person{ } class Student extends Person{ }
super關(guān)鍵字
我們會(huì)發(fā)現(xiàn)在上面的代碼中我使用了一個(gè)super關(guān)鍵字,這個(gè)super關(guān)鍵字有不同的使用方式:注意:在子(派生)類的構(gòu)造函數(shù)中使用this或者返回默認(rèn)對(duì)象之前,必須先通過(guò)super調(diào)用父類的構(gòu)造函數(shù)!
super的使用位置有三個(gè):子類的構(gòu)造函數(shù)、實(shí)例方法、靜態(tài)方法;
繼承內(nèi)置類
我們也可以讓我們的類繼承自內(nèi)置類,比如Array:
class HYArray extends Array { firstItem() { return this[0] } lastItem() { return this[this.length-1] } } var arr = new HYArray(1, 2, 3) console.log(arr.firstItem()) console.log(arr.lastItem())
類的混入mixin
JavaScript的類只支持單繼承:也就是只能有一個(gè)父類 。那么在開(kāi)發(fā)中我們我們需要在一個(gè)類中添加