JavaScript面向?qū)ο笾钊肓私釫S6的class
前言
在前面一篇中主要介紹了JavaScript中使用構(gòu)造函數(shù)+原型鏈實(shí)現(xiàn)繼承,從實(shí)現(xiàn)的步驟來說還是比較繁瑣的。在ES6中推出的class的關(guān)鍵字可以直接用來定義類,寫法類似與其它的面向?qū)ο笳Z言,但是使用class來定義的類其本質(zhì)上依然是構(gòu)造函數(shù)+原型鏈的語法糖而已,下面就一起來全面的了解一下class吧。
1.類的定義
class關(guān)鍵字定義類可使用兩種方式來定義:
class Person {} // 類聲明 const Person = class {} // 類表達(dá)式
2.類的構(gòu)造函數(shù)
從上面class定義類可以發(fā)現(xiàn)是沒有()讓我們來傳遞參數(shù)的,當(dāng)希望在實(shí)例化對象的給類傳遞一些參數(shù),這個(gè)時(shí)候就可以使用到類的構(gòu)造函數(shù)constructor了。
每個(gè)類都可以有一個(gè)自己的constructor方法,注意只能有一個(gè),如果有多個(gè)會拋出異常;
class Person { constructor(name, age) { this.name = name this.age = age } constructor() {} }
當(dāng)通過new操作符來操作類時(shí),就會去調(diào)用這個(gè)類的constructor方法,并返回一個(gè)對象(具體new操作符調(diào)用函數(shù)時(shí)的默認(rèn)操作步驟在上一篇中有說明);
class Person { constructor(name, age) { this.name = name this.age = age } } const p = new Person('curry', 30) console.log(p) // Person { name: 'curry', age: 30 }
3.類的實(shí)例方法
在構(gòu)造函數(shù)中實(shí)現(xiàn)方法繼承是將其放到構(gòu)造函數(shù)的原型上,而在class定義的類中,可直接在類中定義方法,最終class還是會幫我們放到其原型上,供多個(gè)實(shí)例來使用。
class Person { constructor(name, age) { this.name = name this.age = age } eating() { console.log(this.name + 'is eating.') } running() { console.log(this.name + 'is running.') } }
4.類的訪問器方法
在使用Object.defineProperty()
方法來控制對象的屬性時(shí),在其數(shù)據(jù)屬性描述符中可以使用setter和getter函數(shù),在class定義的類中,也是可以使用這兩個(gè)訪問器方法的。
class Person { constructor(name, age) { this.name = name this._age = 30 // 使用_定義的屬性表示為私有屬性,不可直接訪問 } get age() { console.log('age被訪問') return this._age } set age(newValue) { console.log('age被設(shè)置') this._age = newValue } } const p = new Person('curry', 30) console.log(p) // Person { name: 'curry', _age: 30 } p.age // age被訪問 p.age = 24 // age被設(shè)置 console.log(p) // Person { name: 'curry', _age: 24 }
5.類的靜態(tài)方法
什么叫類的靜態(tài)方法呢?該方法不是供實(shí)例對象來使用的,而是直接加在類本身的方法,可以使用類名點(diǎn)出來的方法,可以使用static關(guān)鍵字來定義靜態(tài)方法。
class Person { constructor(name, age) { this.name = name this.age = age } static foo() { console.log('我是Person類的方法') } } Person.foo() // 我是Person類的方法
6.類的繼承
6.1.extends關(guān)鍵字
在ES6之前實(shí)現(xiàn)繼承是不方便的,ES6中增加了extends關(guān)鍵字,可以方便的幫助我們實(shí)現(xiàn)類的繼承。
實(shí)現(xiàn)Student子類繼承自Person父類:
class Person { constructor(name, age) { this.name = name this.age = age } eating() { console.log(this.name + ' is eating.') } } class Student extends Person { constructor(sno) { this.sno = sno } studying() { console.log(this.name + ' is studying.') } }
那么子類如何使用父類的屬性和方法呢?
6.2.super關(guān)鍵字
使用super關(guān)鍵字可以在子類構(gòu)造函數(shù)中調(diào)用父類的構(gòu)造函數(shù),但是必須在子類構(gòu)造函數(shù)中使用this或者返回默認(rèn)對象之前使用super。
class Person { constructor(name, age) { this.name = name this.age = age } eating() { console.log(this.name + ' is eating.') } } class Student extends Person { constructor(name, age, sno) { super(name, age) this.sno = sno } studying() { console.log(this.name + ' is studying.') } } const stu = new Student('curry', 30, 101111) console.log(stu) // Student { name: 'curry', age: 30, sno: 101111 } // 父類的方法可直接調(diào)用 stu.eating() // curry is eating. stu.studying() // curry is studying.
但是super關(guān)鍵字的用途并不僅僅只有這個(gè),super關(guān)鍵字一般可以在三個(gè)地方使用:
- 子類的構(gòu)造函數(shù)中(上面的用法);
- 實(shí)例方法中:子類不僅可以重寫父類中的實(shí)例方法,還可以通過super關(guān)鍵字復(fù)用父類實(shí)例方法中的邏輯代碼;
class Person { constructor(name, age) { this.name = name this.age = age } eating() { console.log(this.name + ' is eating.') } parentMethod() { console.log('父類邏輯代碼1') console.log('父類邏輯代碼2') console.log('父類邏輯代碼3') } } class Student extends Person { constructor(name, age, sno) { super(name, age) this.sno = sno } // 直接重寫父類eating方法 eating() { console.log('Student is eating.') } // 重寫父類的parentMethod方法,并且復(fù)用邏輯代碼 parentMethod() { // 通過super調(diào)用父類方法,實(shí)現(xiàn)復(fù)用 super.parentMethod() console.log('子類邏輯代碼4') console.log('子類邏輯代碼5') console.log('子類邏輯代碼6') } }
靜態(tài)方法中:用法就和實(shí)例方法的方式一樣了;
class Person { constructor(name, age) { this.name = name this.age = age } static parentMethod() { console.log('父類邏輯代碼1') console.log('父類邏輯代碼2') console.log('父類邏輯代碼3') } } class Student extends Person { constructor(name, age, sno) { super(name, age) this.sno = sno } // 重寫父類的parentMethod靜態(tài)方法,并且復(fù)用邏輯代碼 static parentMethod() { // 通過super調(diào)用父類靜態(tài)方法,實(shí)現(xiàn)復(fù)用 super.parentMethod() console.log('子類邏輯代碼4') console.log('子類邏輯代碼5') console.log('子類邏輯代碼6') } } Student.parentMethod()
6.3.繼承內(nèi)置類
extends關(guān)鍵字不僅可以實(shí)現(xiàn)繼承我們自定義的父類,還可以繼承JavaScript提供的內(nèi)置類,可對內(nèi)置類的功能進(jìn)行擴(kuò)展。
比如,在Array
類上擴(kuò)展兩個(gè)方法,一個(gè)方法獲取指定數(shù)組的第一個(gè)元素,一個(gè)方法數(shù)組的最后一個(gè)元素:
class myArray extends Array { firstItem() { return this[0] } lastItem() { return this[this.length - 1] } } const arr = new myArray(1, 2, 3) console.log(arr) // myArray(3) [ 1, 2, 3 ] console.log(arr.firstItem()) // 1 console.log(arr.lastItem()) // 3
7.類的混入
何為類的混入?在上面的演示代碼中,都只實(shí)現(xiàn)了子類繼承自一個(gè)父類,因?yàn)镴avaScript的類只支持單繼承,不能繼承自多個(gè)類。如果非要實(shí)現(xiàn)繼承自多個(gè)類呢?那么就可以引入混入(Mixin)的概念了。
看看JavaScript中通過代碼如何實(shí)現(xiàn)混入效果:
// 封裝混入Animal類的函數(shù) function mixinClass(BaseClass) { // 返回一個(gè)匿名類 return class extends BaseClass { running() { console.log('running...') } } } class Person { eating() { console.log('eating...') } } class Student extends Person { studying() { console.log('studying...') } } const NewStudent = mixinClass(Student) const stu = new NewStudent stu.running() // running... stu.eating() // eating... stu.studying() // studying...
混入的實(shí)現(xiàn)一般不常用,因?yàn)閰?shù)不太好傳遞,過于局限,在JavaScript中單繼承已經(jīng)足夠用了。
8.class定義類轉(zhuǎn)ES5
上面介紹ES6中類的各種使用方法,極大的方便了我們對類的使用。我們在日常開發(fā)中編寫的ES6代碼都是會被babel解析成ES5代碼,為了對低版本瀏覽器做適配。那么使用ES6編寫的類被編譯成ES5語法會是什么樣呢?通過babel官網(wǎng)的試一試可以清楚的看到ES6語法轉(zhuǎn)成ES5后的樣子。
- 剛開始通過執(zhí)行自調(diào)用函數(shù)得到一個(gè)Person構(gòu)造函數(shù);
- 定義的實(shí)例方法和類方法會分別收集到一個(gè)數(shù)組中,便于后面直接調(diào)用函數(shù)進(jìn)行遍歷添加;
- 判斷方法類型:如果是實(shí)例方法就添加到Person原型上,是類方法直接添加到Person上;
- 所以class定義類的本質(zhì)還是通過構(gòu)造函數(shù)+原型鏈,class就是一種語法糖;
這里可以提出一個(gè)小問題:定義在constructor外的屬性最終會被添加到哪里呢?還是會被添加到類的實(shí)例化對象上,因?yàn)镋S6對這樣定義的屬性進(jìn)行了單獨(dú)的處理。
class Person { message = 'hello world' constructor(name, age) { this.name = name this.age = age } eating() { console.log(this.name + ' is eating.') } static personMethod() { console.log('personMethod') } } const p = new Person('curry', 30) console.log(p) // Person { message: 'hello world', name: 'curry', age: 30 }
擴(kuò)展:在上圖中通過通過babel轉(zhuǎn)換后的代碼中,定義的Person函數(shù)前有一個(gè)/*#__PURE__*/
,那么這個(gè)有什么作用呢?
- 實(shí)際上這個(gè)符號將函數(shù)標(biāo)記為了純函數(shù),在JavaScript中純函數(shù)的特點(diǎn)就是沒有副作用,不依賴于其它東西,獨(dú)立性很強(qiáng);
- 在使用webpack構(gòu)建的項(xiàng)目中,通過babel轉(zhuǎn)換后的語法更有利于webpack進(jìn)行
tree-shaking
,沒有使用到的純函數(shù)會直接在打包的時(shí)候被壓縮掉,達(dá)到減小包體積效果;
總結(jié)
到此這篇關(guān)于JavaScript面向?qū)ο笾钊肓私釫S6的class的文章就介紹到這了,更多相關(guān)了解ES6的class內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
js實(shí)現(xiàn)鍵盤上下左右鍵選擇文字并顯示在文本框的方法
這篇文章主要介紹了js實(shí)現(xiàn)鍵盤上下左右鍵選擇文字并顯示在文本框的方法,涉及javascript操作鍵盤事件及文本框的相關(guān)技巧,非常簡單實(shí)用,需要的朋友可以參考下2015-05-05js求數(shù)組中全部數(shù)字可拼接出的最大整數(shù)示例代碼
這篇文章主要給大家介紹了利用js如何求數(shù)組中全部數(shù)字可拼接出的最大整數(shù),文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考借鑒,下面隨著小編一起來學(xué)習(xí)學(xué)習(xí)吧。2017-08-08JS事件循環(huán)機(jī)制event loop宏任務(wù)微任務(wù)原理解析
這篇文章主要介紹了JS事件循環(huán)機(jī)制event loop宏任務(wù)微任務(wù)原理解析,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友可以參考下2020-08-08TypeScript內(nèi)置工具類型快速入門運(yùn)用
TypeScript 中內(nèi)置了很多工具類型,我們無需導(dǎo)入,可以直接使用。 其中的很多都是比較常用的,接下來我們根據(jù)使用范圍來一一介紹,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面隨著小編來一起學(xué)習(xí)吧2023-03-03js 定義對象數(shù)組(結(jié)合)多維數(shù)組方法
下面小編就為大家?guī)硪黄猨s 定義對象數(shù)組(結(jié)合)多維數(shù)組方法。小編覺得挺不錯(cuò)的,現(xiàn)在就分享給大家,也給大家做個(gè)參考。一起跟隨小編過來看看吧2016-07-07JavaScript數(shù)組,JSON對象實(shí)現(xiàn)動態(tài)添加、修改、刪除功能示例
這篇文章主要介紹了JavaScript數(shù)組,JSON對象實(shí)現(xiàn)動態(tài)添加、修改、刪除功能,結(jié)合實(shí)例形式分析了JavaScript針對json數(shù)組的添加、刪除、修改操作實(shí)現(xiàn)技巧,需要的朋友可以參考下2018-05-05ElementUI中el-tree如何獲取每個(gè)節(jié)點(diǎn)點(diǎn)擊的選中狀態(tài)
ElementUI中el-tree獲取每個(gè)節(jié)點(diǎn)點(diǎn)擊的選中狀態(tài),有時(shí)候需要獲取el-tree每個(gè)節(jié)點(diǎn)的點(diǎn)擊狀態(tài),可以通過以下方式,其中isCheck類型為布爾值,本文結(jié)合實(shí)例代碼介紹ElementUI中el-tree獲取每個(gè)節(jié)點(diǎn)點(diǎn)擊的選中狀態(tài),感興趣的朋友一起看看吧2023-12-12