ES6 類class

一吠架、簡(jiǎn)介

JavaScript 語(yǔ)言中锋喜,生成實(shí)例對(duì)象的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù)凡涩。下面是一個(gè)例子棒搜。

function Person(name, age){
  this.name = name;
  this.age = age;
}

Person.prototype.showName = function(){
  return this.name;
}

var p1 = new Person('jack', 24);
console.log(p1.showName());  // jack

ES6 提供了更接近傳統(tǒng)語(yǔ)言的寫(xiě)法,引入了 Class(類)這個(gè)概念活箕,作為對(duì)象的模板力麸。通過(guò) class 關(guān)鍵字,可以定義類育韩。

基本上克蚂,ES6 的 class 可以看作只是一個(gè)語(yǔ)法糖,它的絕大部分功能筋讨,ES5 都可以做到埃叭,新的 class 寫(xiě)法只是讓對(duì)象原型的寫(xiě)法更加清晰、更像面向?qū)ο缶幊痰恼Z(yǔ)法而已悉罕。上面的代碼用 ES6 的 class 改寫(xiě)赤屋,就是下面這樣误墓。

//定義類
class Person{
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }

  showName() {
    return this.name;
  }
}

上面代碼定義了一個(gè)“類”,可以看到里面有一個(gè) constructor 方法益缎,這就是構(gòu)造方法,而 this 關(guān)鍵字則代表實(shí)例對(duì)象然想。也就是說(shuō)莺奔,ES5 的構(gòu)造函數(shù) Person,對(duì)應(yīng) ES6 的 Person 類的構(gòu)造方法变泄。

Person 類除了構(gòu)造方法令哟,還定義了一個(gè) showName 方法。注意妨蛹,定義“類”的方法的時(shí)候屏富,前面不需要加上 function 這個(gè)關(guān)鍵字,直接把函數(shù)定義放進(jìn)去了就可以了蛙卤。另外狠半,方法之間不需要逗號(hào)分隔,加了會(huì)報(bào)錯(cuò)颤难。

ES6 的類神年,完全可以看作構(gòu)造函數(shù)的另一種寫(xiě)法。

class Person{
}

typeof Person  // "function"
Person === Person.prototype.constructor // true

上面代碼表明行嗤,類的數(shù)據(jù)類型就是函數(shù)已日,類本身就指向構(gòu)造函數(shù)。

使用的時(shí)候栅屏,也是直接對(duì)類使用 new 命令飘千,跟構(gòu)造函數(shù)的用法完全一致。

二栈雳、嚴(yán)格模式

嚴(yán)格模式
類和模塊的內(nèi)部护奈,默認(rèn)就是嚴(yán)格模式,所以不需要使用use strict指定運(yùn)行模式甫恩。只要你的代碼寫(xiě)在類或模塊之中逆济,就只有嚴(yán)格模式可用。

考慮到未來(lái)所有的代碼磺箕,其實(shí)都是運(yùn)行在模塊之中奖慌,所以 ES6 實(shí)際上把整個(gè)語(yǔ)言升級(jí)到了嚴(yán)格模式。

三松靡、constructor 方法

constructor 方法是類的默認(rèn)方法简僧,通過(guò) new 命令生成對(duì)象實(shí)例時(shí),自動(dòng)調(diào)用該方法雕欺。一個(gè)類必須有constructor 方法岛马,如果沒(méi)有顯式定義棉姐,一個(gè)空的 constructor 方法會(huì)被默認(rèn)添加。

class Person {
}

// 等同于
class Person {
  constructor() {}
}

四啦逆、Class 的繼承

Class 可以通過(guò) extends 關(guān)鍵字實(shí)現(xiàn)繼承伞矩,這比 ES5 的通過(guò)修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多夏志。

class Person {
}

class Man extends Person {
}

上面代碼定義了一個(gè) Man 類乃坤,該類通過(guò) extends 關(guān)鍵字,繼承了 Person 類的所有屬性和方法沟蔑。但是由于沒(méi)有部署任何代碼湿诊,所以這兩個(gè)類完全一樣,等于復(fù)制了一個(gè) Person 類瘦材。下面厅须,我們?cè)?Man 內(nèi)部加上代碼。

class Man extends Person {
  constructor(name, age, job) {
    super(name, age);                                              //  調(diào)用父類的constructor(name, age)
    this.job = job;
  }

  showJob() {
    return 'My name is ' + super.showName() + ',I am a ' + this.job;   // 調(diào)用父類的 sayName()
  }
}

var person1 = new Man('jack',26,'FED');
console.log(person1.sayJob()) // "My name is jack,I am a FED"

上面代碼中食棕,constructor 方法和 showJob 方法之中朗和,都出現(xiàn)了super關(guān)鍵字,它在這里表示父類的構(gòu)造函數(shù)簿晓,用來(lái)新建父類的 this 對(duì)象例隆。

子類必須在 constructor 方法中調(diào)用 super 方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)抢蚀。這是因?yàn)樽宇悰](méi)有自己的 this
對(duì)象镀层,而是繼承父類的 this 對(duì)象,然后對(duì)其進(jìn)行加工皿曲。如果不調(diào)用 super 方法唱逢,子類就得不到 this 對(duì)象。

class Person { 
}

class Man extends Person {
  constructor() {
  }
}

var man = new Man(); // ReferenceError

上面代碼中屋休,Man 繼承了父類 Person坞古,但是它的構(gòu)造函數(shù)沒(méi)有調(diào)用 super 方法,導(dǎo)致新建實(shí)例時(shí)報(bào)錯(cuò)劫樟。

ES5 的繼承痪枫,實(shí)質(zhì)是先創(chuàng)造子類的實(shí)例對(duì)象 this,然后再將父類的方法添加到 this 上面(Parent.apply(this))叠艳。ES6 的繼承機(jī)制完全不同奶陈,實(shí)質(zhì)是先創(chuàng)造父類的實(shí)例對(duì)象this(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改 this附较。

如果子類沒(méi)有定義 constructor 方法吃粒,這個(gè)方法會(huì)被默認(rèn)添加,代碼如下拒课。也就是說(shuō)徐勃,不管有沒(méi)有顯式定義事示,任何一個(gè)子類都有 constructor 方法。

class Man extends Person {
}

// 等同于
class Man extends Person {
  constructor(...args) {
    super(...args);
  }
}

另一個(gè)需要注意的地方是僻肖,在子類的構(gòu)造函數(shù)中肖爵,只有調(diào)用 super 之后,才可以使用this關(guān)鍵字臀脏,否則會(huì)報(bào)錯(cuò)遏匆。這是因?yàn)樽宇悓?shí)例的構(gòu)建,是基于對(duì)父類實(shí)例加工谁榜,只有 super 方法才能返回父類實(shí)例。

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}

class Man extends Person {
  constructor(name, age, job) {
    this.job = job; // ReferenceError
    super(name, age);
    this.job = job; // 正確
  }
}

上面代碼中凡纳,子類的 constructor 方法沒(méi)有調(diào)用 super 之前窃植,就使用 this 關(guān)鍵字,結(jié)果報(bào)錯(cuò)荐糜,而放在
super 方法之后就是正確的巷怜。
下面是生成子類實(shí)例的代碼。

let man = new Man('jack', 26, 'FED');

man instanceof Man // true
man instanceof Person // true

上面代碼中暴氏,實(shí)例對(duì)象 man 同時(shí)是 ManPerson 兩個(gè)類的實(shí)例延塑,這與 ES5 的行為完全一致。

最后答渔,父類的靜態(tài)方法关带,也會(huì)被子類繼承。

class A {
  static hello() {
    console.log('hello world');
  }
}

class B extends A {
}

B.hello()  // hello world

上面代碼中沼撕,hello()是A類的靜態(tài)方法宋雏,B繼承A,也繼承了A的靜態(tài)方法务豺。

五磨总、super關(guān)鍵字

super 這個(gè)關(guān)鍵字,既可以當(dāng)作函數(shù)使用笼沥,也可以當(dāng)作對(duì)象使用蚪燕。在這兩種情況下,它的用法完全不同奔浅。

第一種情況馆纳,super 作為函數(shù)調(diào)用時(shí),代表父類的構(gòu)造函數(shù)汹桦。ES6 要求厕诡,子類的構(gòu)造函數(shù)必須執(zhí)行一次super 函數(shù)。

class A {}

class B extends A {
  constructor() {
    super();
  }
}

上面代碼中营勤,子類B的構(gòu)造函數(shù)之中的super()灵嫌,代表調(diào)用父類的構(gòu)造函數(shù)壹罚。這是必須的,否則 JavaScript 引擎會(huì)報(bào)錯(cuò)寿羞。
(略)

參考:

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末猖凛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子绪穆,更是在濱河造成了極大的恐慌辨泳,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件玖院,死亡現(xiàn)場(chǎng)離奇詭異菠红,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)难菌,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評(píng)論 2 384
  • 文/潘曉璐 我一進(jìn)店門(mén)试溯,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人郊酒,你說(shuō)我怎么就攤上這事遇绞。” “怎么了燎窘?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,723評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵摹闽,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我褐健,道長(zhǎng)付鹿,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,357評(píng)論 1 283
  • 正文 為了忘掉前任蚜迅,我火速辦了婚禮倘屹,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘慢叨。我一直安慰自己纽匙,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,412評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布拍谐。 她就那樣靜靜地躺著烛缔,像睡著了一般。 火紅的嫁衣襯著肌膚如雪轩拨。 梳的紋絲不亂的頭發(fā)上践瓷,一...
    開(kāi)封第一講書(shū)人閱讀 49,760評(píng)論 1 289
  • 那天,我揣著相機(jī)與錄音亡蓉,去河邊找鬼晕翠。 笑死,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的淋肾。 我是一名探鬼主播硫麻,決...
    沈念sama閱讀 38,904評(píng)論 3 405
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼樊卓!你這毒婦竟也來(lái)了拿愧?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 37,672評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤碌尔,失蹤者是張志新(化名)和其女友劉穎浇辜,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體唾戚,經(jīng)...
    沈念sama閱讀 44,118評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡柳洋,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,456評(píng)論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了叹坦。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片熊镣。...
    茶點(diǎn)故事閱讀 38,599評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖立由,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情序厉,我是刑警寧澤锐膜,帶...
    沈念sama閱讀 34,264評(píng)論 4 328
  • 正文 年R本政府宣布,位于F島的核電站弛房,受9級(jí)特大地震影響道盏,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜文捶,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,857評(píng)論 3 312
  • 文/蒙蒙 一荷逞、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧粹排,春花似錦种远、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,731評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至射富,卻和暖如春膝迎,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背胰耗。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,956評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工限次, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人柴灯。 一個(gè)月前我還...
    沈念sama閱讀 46,286評(píng)論 2 360
  • 正文 我出身青樓卖漫,卻偏偏與公主長(zhǎng)得像费尽,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子懊亡,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,465評(píng)論 2 348

推薦閱讀更多精彩內(nèi)容

  • class的基本用法 概述 JavaScript語(yǔ)言的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù)依啰,定義并生成新對(duì)象。下面是一個(gè)例子: ...
    呼呼哥閱讀 4,086評(píng)論 3 11
  • 假如我們想要?jiǎng)?chuàng)建一個(gè)經(jīng)典的面向?qū)ο笤O(shè)計(jì)示例:Circle類店枣。想象一下我們正在為一個(gè)簡(jiǎn)單的Canvas庫(kù)編寫(xiě)這個(gè)Ci...
    糖心m閱讀 383評(píng)論 0 2
  • 1. Java基礎(chǔ)部分 基礎(chǔ)部分的順序:基本語(yǔ)法速警,類相關(guān)的語(yǔ)法,內(nèi)部類的語(yǔ)法鸯两,繼承相關(guān)的語(yǔ)法闷旧,異常的語(yǔ)法,線程的語(yǔ)...
    子非魚(yú)_t_閱讀 31,598評(píng)論 18 399
  • 一:java概述:1钧唐,JDK:Java Development Kit忙灼,java的開(kāi)發(fā)和運(yùn)行環(huán)境,java的開(kāi)發(fā)工...
    ZaneInTheSun閱讀 2,635評(píng)論 0 11
  • ▽ 然而內(nèi)褲并沒(méi)干 因?yàn)樗羌兠薜?/div>
    我很可口嘛閱讀 957評(píng)論 32 26