- 相關(guān)推薦
JavaScript ES6中CLASS的使用指南
1、前言
對于javascript來(lái)說(shuō),類(lèi)是一種可選(而不是必須)的設計模式,而且在JavaScript這樣的[[Prototype]] 語(yǔ)言中實(shí)現類(lèi)是很蹩腳的。
這種蹩腳的感覺(jué)不只是來(lái)源于語(yǔ)法,雖然語(yǔ)法是很重要的原因。js里面有許多語(yǔ)法的缺點(diǎn):繁瑣雜亂的.prototype 引用、試圖調用原型鏈上層同名函數時(shí)的顯式偽多態(tài)以及不可靠、不美觀(guān)而且容易被誤解成“構造函數”的.constructor。
除此之外,類(lèi)設計其實(shí)還存在更進(jìn)一步的問(wèn)題。傳統面向類(lèi)的語(yǔ)言中父類(lèi)和子類(lèi)、子類(lèi)和實(shí)例之間其實(shí)是復制操作,但是在[[Prototype]] 中并沒(méi)有復制。
對象關(guān)聯(lián)代碼和行為委托使用了[[Prototype]] 而不是將它藏起來(lái),對比其簡(jiǎn)潔性可以看出,類(lèi)并不適用于JavaScript。
2、ES6中CLASS的使用
javascript傳統做法是當生成一個(gè)對象實(shí)例,需要定義構造函數,然后通過(guò)new的方式完成。
function StdInfo(){ this.name = "job"; this.age = 30; }StdInfo.prototype.getNames = function (){ console.log("name:"+this.name); }//得到一個(gè)學(xué)員信息對象var p = new StdInfo()
javacript中只有對象,沒(méi)有類(lèi)。它是是基于原型的語(yǔ)言,原型對象是新對象的模板,它將自身的屬性共享給新對象。這樣的寫(xiě)法和傳統面向對象語(yǔ)言差異很大,很容易讓新手感到困惑。
3、定義類(lèi)
到了ES6添加了類(lèi),作為對象的模板。通過(guò)class來(lái)定義一個(gè)類(lèi):
//定義類(lèi)class StdInfo { constructor(){ this.name = "job"; this.age = 30; } //定義在類(lèi)中的方法不需要添加function getNames(){ console.log("name:"+this.name); }}//使用new的方式得到一個(gè)實(shí)例對象var p = new StdInfo();
上面的寫(xiě)法更加清晰、更像面向對象編程的語(yǔ)法,看起來(lái)也更容易理解。
定義的類(lèi)只是語(yǔ)法糖,目的是讓我們用更簡(jiǎn)潔明了的語(yǔ)法創(chuàng )建對象及處理相關(guān)的繼承。
//定義類(lèi)class StdInfo { //...}console.log(typeof StdInfo); //functionconsole.log(StdInfo === StdInfo.prototype.constructor); //true
從上面的測試中可以看出來(lái),類(lèi)的類(lèi)型就是一個(gè)函數,是一個(gè)“特殊函數”,指向的是構造函數。
函數的定義方式有函數聲明和函數表達式兩種,類(lèi)的定義方式也有兩種,分別是:類(lèi)聲明和類(lèi)表達式。
4、類(lèi)聲明
類(lèi)聲明是定義類(lèi)的一種方式,使用關(guān)鍵字class,后面跟上類(lèi)名,然后就是一對大括號。把這一類(lèi)需要定義的方法放在大括號中。
//定義類(lèi),可以省略constructorclass StdInfo { getNames(){ console.log("name:"+this.name); }}// -------------------------------------//定義類(lèi),加上constructorclass StdInfo { //使用new定義實(shí)例對象時(shí),自動(dòng)調用這個(gè)函數,傳入參數 constructor(name,age){ this.name = name; this.age = age; } getNames(){ console.log("name:"+this.name); }}//定義實(shí)例對象時(shí),傳入參數var p = new StdInfo("job",30)
constructor是一個(gè)默認方法,使用new來(lái)定義實(shí)例對象時(shí),自動(dòng)執行constructor函數,傳入所需要的參數,執行完constructor后自動(dòng)返回實(shí)例對象。
一個(gè)類(lèi)中只能有一個(gè)constructor函數,定義多個(gè)會(huì )報錯。
constructor中的this指向新創(chuàng )建的實(shí)例對象,利用this往新創(chuàng )建的實(shí)例對象擴展屬性。
在定義實(shí)例對象時(shí),不需要在初始化階段做一些事,可以不用顯示的寫(xiě)constructor函數。如果沒(méi)有顯式定義,一個(gè)空的constructor方法會(huì )被默認添加,constructor(){}
5、類(lèi)表達式
類(lèi)表達式是定義類(lèi)的另一種形式,類(lèi)似于函數表達式,把一個(gè)函數作為值賦給變量?梢园讯x的類(lèi)賦值給一個(gè)變量,這時(shí)候變量就為類(lèi)名。class關(guān)鍵字之后的類(lèi)名可有可無(wú),如果存在,則只能在類(lèi)內部使用。
定義類(lèi) class后面有類(lèi)名:
const People = class StdInfo { constructor(){ console.log(StdInfo); //可以打印出值,是一個(gè)函數 }}new People();new StdInfo(); //報錯,StdInfo is not defined;
定義類(lèi) class后面沒(méi)有類(lèi)名:
const People = class { constructor(){ }}new People();
立即執行的類(lèi):
const p = new class { constructor(name,age){ console.log(name,age); }}("job",30)
立即執行的類(lèi),在類(lèi)前要加上new。p為類(lèi)的實(shí)例對象。
6、不存在變量提升
定義類(lèi)不存在變量提升,只能先定義類(lèi)后使用,跟函數聲明有區別的。
//-----函數聲明-------//定義前可以先使用,因為函數聲明提升的緣故,調用合法。func();function func(){}//-----定義類(lèi)---------------new StdInfo(); //報錯,StdInfo is not definedclass StdInfo{}
7、EXTENDS繼承
使用extends關(guān)鍵字實(shí)現類(lèi)之間的繼承。這比在ES5中使用繼承要方便很多。
//定義類(lèi)父類(lèi)class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); }}//定義子類(lèi),繼承父類(lèi)class Child extends Parent { coding(){ console.log("coding javascript"); }}var c = new Child();//可以調用父類(lèi)的方法c.speakSometing(); // I can speek chinese使用繼承的方式,子類(lèi)就擁有了父類(lèi)的方法。
如果子類(lèi)中有constructor構造函數,則必須使用調用super。
//定義類(lèi)父類(lèi)class Parent { constructor(name,age){ this.name = name; this.age = age; } speakSometing(){ console.log("I can speek chinese"); }}//定義子類(lèi),繼承父類(lèi)class Child extends Parent { constructor(name,age){ //不調super(),則會(huì )報錯 this is not defined //必須調用super super(name,age); } coding(){ console.log("coding javascript"); }}var c = new Child("job",30);//可以調用父類(lèi)的方法c.speakSometing(); // I can speek chinese
子類(lèi)必須在constructor方法中調用super方法,否則新建實(shí)例時(shí)會(huì )報錯(this is not defined)。這是因為子類(lèi)沒(méi)有自己的this對象,而是繼承父類(lèi)的this對象,然后對其進(jìn)行加工。如果不調用super方法,子類(lèi)就得不到this對象。
8、總結
好了,以上就是對ES6中類(lèi)的簡(jiǎn)單總結學(xué)習,希望本文的內容對大家的學(xué)習或者工作能帶來(lái)一定的幫助,如果有疑問(wèn)大家可以留言交流,謝謝大家對的支持。
【JavaScript ES6中CLASS的使用指南】相關(guān)文章:
perl- javascript中class的機制05-03
JavaScript中的with關(guān)鍵字07-24
在Java中執行JavaScript代碼07-14
抽象語(yǔ)法樹(shù)在JavaScript中的應用08-18
JavaScript中的三種對象10-24
JavaScript中push(),join() 函數實(shí)例詳解09-05
詳解JavaScript中的splice()使用方法08-20