Class 的那些事兒

ES6 引入了Class(類)這個(gè)概念,作為對(duì)象的模板迂苛,通過(guò)class關(guān)鍵字三热,可以定義類。

class Point {
  constructor(x,y) {
    this.x = x;
    this.y = y;
  } 
}
  • 類的數(shù)據(jù)類型就是函數(shù)三幻,類本身就是指向構(gòu)造函數(shù)就漾。
  • 使用的時(shí)候,也是直接對(duì)類使用new命令念搬,跟構(gòu)造函數(shù)的用法完全一致抑堡。
  • ES6中,類的所有方法都定義在類的prototype屬性上面锁蠕。
class Point {
  constructor () {
    // do sth
  }
  toValue () {
    // do sth  
  }
}
// 等同于
Point.prototype = {
  construcror () {},
  toValue () {}
}
  • 在類的實(shí)例上面調(diào)用方法夷野,其實(shí)就是調(diào)用原型上的方法。
class B ()
let b = new B();
b.constructor === B.prototype.constructor; // true
  • prototype對(duì)象的constructor屬性荣倾,直接指向“類”的本身悯搔。
class MyPoint{
    constructor(props){
        this.x = props.x;
        this.y = props.y;
    }
}
var myPoint = new MyPoint({x:1,y:2});
myPoint.constructor === MyPoint; // => true
MyPoint.prototype.constructor === MyPoint; // => true
  • 類的內(nèi)部所有定義的方法,都是不可枚舉的。(non-enumerable)
  class MyPoint {
        constructor(props) {
            this.x = props.x;
            this.y = props.y;
        }
        sum() {
            console.log(this.x + this.y);
        }
    }
    var myPoint = new MyPoint({
        x: 1,
        y: 3
    });
    myPoint.sum(); // => 4
    var keys = Object.keys(MyPoint.prototype);
    console.log(keys); // => []

constructor 方法

constructor方法是默認(rèn)方法妒貌,通過(guò)new命令生成對(duì)象實(shí)例時(shí)通危,自動(dòng)調(diào)用該方法,一個(gè)類必須有constructor方法灌曙,如果沒(méi)有顯示定義菊碟,一個(gè)空的constructor方法會(huì)被默認(rèn)添加。

  class MyPoint {
    
  }
  // 等同于
  class MyPoint {
     constructor(){}
  }
  • js引擎會(huì)自動(dòng)為它添加一個(gè)空的constructor方法在刺。
  • constructor方法默認(rèn)返回實(shí)例對(duì)象(即this)逆害,完全可以指定返回另外一個(gè)對(duì)象
  class Foo{
        constructor(){
            var p = {x:'scp'};
            return Object.create(p);  // 返回一個(gè)全新的對(duì)象
        }
    }
    // 實(shí)例對(duì)象不是Foo類的實(shí)例
    console.log(new Foo instanceof Foo); // => false
    // 查詢實(shí)例對(duì)象的原型對(duì)象是 上邊定義的 p
    console.log(Object.getPrototypeOf(new Foo)); // => {x:"scp"}

類的實(shí)例

  • 類必須使用new調(diào)用,否則會(huì)報(bào)錯(cuò)
  • 實(shí)例的屬性除非顯式定義在其本身(即定義在this對(duì)象上)蚣驼,否則都是定義在原型上(即class上)
  class MyPoint {
        constructor(props) {
            this.x = props.x;
            this.y = props.y;
        }
        sum() {
            console.log(this.x + this.y);
        }
    }
    var myPoint = new MyPoint({
        x: 1,
        y: 3
    });
    console.log(myPoint.hasOwnProperty('x')); // => true
    console.log(myPoint.hasOwnProperty('sum'));// =>  false
    console.log(myPoint.__proto__.hasOwnProperty('sum')); // => true

如上魄幕,x是實(shí)例對(duì)象myPoint自身的屬性,sum是定義在原型對(duì)象上的屬性


繼承

Class可以通過(guò) extends關(guān)鍵字實(shí)現(xiàn)繼承

  • ChildrenPoint中的constructor方法中出現(xiàn)的super關(guān)鍵字表示父類的構(gòu)造函數(shù)颖杏,用來(lái)新建父類的this對(duì)象纯陨。

  • 子類必須在constructor中調(diào)用super方法,否則新建實(shí)例時(shí)會(huì)報(bào)錯(cuò)留储,這是因?yàn)樽宇愖约旱?code>this對(duì)象翼抠,必須先通過(guò)父類的構(gòu)造函數(shù)完成塑造,得到與父類同樣的實(shí)例屬性和方法获讳,然后再對(duì)其進(jìn)行加工阴颖,加上子類自己的實(shí)例屬性和方法,如果不調(diào)用super方法赔嚎,子類就得不到this對(duì)象膘盖。

  • 在子類構(gòu)造函數(shù)中,只有調(diào)用super之后尤误,才可以使用this關(guān)鍵字否則報(bào)錯(cuò),這是因?yàn)樽宇悓?shí)例的構(gòu)建结缚,基于父類實(shí)例损晤,只有super方法才能調(diào)用父類實(shí)例。

  • ES6 的繼承機(jī)制红竭,實(shí)質(zhì)是先將父類實(shí)例對(duì)象的屬性和方法尤勋,加到this上面(所以必須先調(diào)用super方法),然后再用子類的構(gòu)造函數(shù)修改this茵宪。

  class MyPoint {
        constructor(props) {
            this.x = props.x;
            this.y = props.y;
        }
        sum(...values) {
            console.log(values);
            let summation = values.reduce((prev,cur) => prev + cur,0);
            console.log(summation);
        }
  }
  // 繼承
  class ChildrenPoint extends MyPoint{
        constructor(props,cProps){
            super(props);  // 調(diào)用父類的constructor(props)
            this.w = props.w
            this.z = cProps.z;
        }
   }
   var cPoint = new ChildrenPoint({x:1,y:2,w:3},{z:4});
   cPoint.sum(...Object.values(cPoint)); // => 10

Object.getPrototypeOf()

該方法可以用來(lái)從子類上獲取父類最冰,可以使用這個(gè)方法判定,一個(gè)類是否繼承了另一個(gè)類

console.log(Object.getPrototypeOf(ChildrenPoint) === MyPoint); // => true

super 關(guān)鍵字

  • super可以當(dāng)做函數(shù)使用稀火,只能在子類的構(gòu)造函數(shù)中暖哨,使用,其它地方報(bào)錯(cuò)
  • super可以當(dāng)做對(duì)象使用
  • super作為函數(shù)調(diào)用時(shí)凰狞,代表父類的構(gòu)造函數(shù)篇裁,ES6要求沛慢,子類的構(gòu)造函數(shù)必須執(zhí)行一次super函數(shù)。
  • 子類的構(gòu)造函數(shù)中的super()达布,代表調(diào)用父類的構(gòu)造函數(shù)团甲,但是返回的是子類的實(shí)例,即super內(nèi)部的this指的是子類的實(shí)例黍聂。
class A()
class B extends A {
  constructor() {
    super();
  }
}

上面代碼躺苦,super()在這里相當(dāng)于A.prototype.constructor.call(this)

  • super作為對(duì)象時(shí),在普通方法中产还,指向父類的原型對(duì)象匹厘,在靜態(tài)方法中,指向父類
  class MyPoint {
        constructor(props) {
            this.x = props.x;
        }
        sum(...values) {
            console.log(values);
            let summation = values.reduce((prev,cur) => prev + cur,0);
            console.log(summation);
        }
  }
  // 繼承
  class ChildrenPoint extends MyPoint{
        constructor(props,cProps){
            super(props);  // 調(diào)用父類的constructor(props)
            this.y = cProps.y;
        }
        csum(...values){         
           super.sum(...values); //   super作為對(duì)象使用雕沉,相當(dāng)于MyPoint.prototype
        }
   }
   var cPoint = new ChildrenPoint({x:1},{y:4});
   cPoint.sum(...Object.values(cPoint)); // => 10
   cPoint.csum(...Object.values(cPoint)); // => 10

上面代碼中集乔,子類ChildrenPoint當(dāng)中的super.sum(...values),就是將super當(dāng)做一個(gè)對(duì)象使用坡椒,super在普通方法中扰路,指向MyPoint.prototype,所以super.sum(...values)就相當(dāng)于MyPoint.prototype.sum(...values)

因?yàn)?code>super指向父類的原型對(duì)象倔叼,所以定義在父類實(shí)例上的方法或者屬性汗唱,是無(wú)法通過(guò)super調(diào)用的,比如super.x就會(huì)輸出undefined

類的 prototype 屬性和__proto__屬性

  • 子類的__proto__屬性丈攒,表示構(gòu)造函數(shù)的繼承哩罪,總是指向父類
  • 子類的prototype屬性的__proto__屬性,表示方法的繼承巡验,總是指向父類的prototype
class A {
}

class B extends A {
}

B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末际插,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子显设,更是在濱河造成了極大的恐慌框弛,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,198評(píng)論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件捕捂,死亡現(xiàn)場(chǎng)離奇詭異瑟枫,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)指攒,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評(píng)論 3 398
  • 文/潘曉璐 我一進(jìn)店門慷妙,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人允悦,你說(shuō)我怎么就攤上這事膝擂。” “怎么了?”我有些...
    開封第一講書人閱讀 167,643評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵猿挚,是天一觀的道長(zhǎng)咐旧。 經(jīng)常有香客問(wèn)我,道長(zhǎng)绩蜻,這世上最難降的妖魔是什么铣墨? 我笑而不...
    開封第一講書人閱讀 59,495評(píng)論 1 296
  • 正文 為了忘掉前任,我火速辦了婚禮办绝,結(jié)果婚禮上伊约,老公的妹妹穿的比我還像新娘。我一直安慰自己孕蝉,他們只是感情好屡律,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,502評(píng)論 6 397
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著降淮,像睡著了一般超埋。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上佳鳖,一...
    開封第一講書人閱讀 52,156評(píng)論 1 308
  • 那天霍殴,我揣著相機(jī)與錄音,去河邊找鬼系吩。 笑死来庭,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的穿挨。 我是一名探鬼主播月弛,決...
    沈念sama閱讀 40,743評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼科盛!你這毒婦竟也來(lái)了帽衙?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 39,659評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤贞绵,失蹤者是張志新(化名)和其女友劉穎佛寿,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體但壮,經(jīng)...
    沈念sama閱讀 46,200評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,282評(píng)論 3 340
  • 正文 我和宋清朗相戀三年常侣,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了蜡饵。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,424評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胳施,死狀恐怖溯祸,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情,我是刑警寧澤焦辅,帶...
    沈念sama閱讀 36,107評(píng)論 5 349
  • 正文 年R本政府宣布博杖,位于F島的核電站,受9級(jí)特大地震影響筷登,放射性物質(zhì)發(fā)生泄漏剃根。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,789評(píng)論 3 333
  • 文/蒙蒙 一前方、第九天 我趴在偏房一處隱蔽的房頂上張望狈醉。 院中可真熱鬧,春花似錦惠险、人聲如沸苗傅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評(píng)論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)渣慕。三九已至,卻和暖如春抱慌,著一層夾襖步出監(jiān)牢的瞬間逊桦,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評(píng)論 1 271
  • 我被黑心中介騙來(lái)泰國(guó)打工遥缕, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留卫袒,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,798評(píng)論 3 376
  • 正文 我出身青樓单匣,卻偏偏與公主長(zhǎng)得像夕凝,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子户秤,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,435評(píng)論 2 359

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

  • 簡(jiǎn)介 Class 可以通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承码秉,這比 ES5 的通過(guò)修改原型鏈實(shí)現(xiàn)繼承,要清晰和方便很多鸡号。...
    emmet7life閱讀 357評(píng)論 0 0
  • 基本語(yǔ)法 簡(jiǎn)介 JavaScript語(yǔ)言中,生成實(shí)例對(duì)象的傳統(tǒng)方法是通過(guò)構(gòu)造函數(shù). ES6提供更接近傳統(tǒng)語(yǔ)言的寫法...
    JarvanZ閱讀 881評(píng)論 0 0
  • 簡(jiǎn)介 Class可以通過(guò)extends關(guān)鍵字實(shí)現(xiàn)繼承转砖。 上面代碼定義了一個(gè)ColorPoint類,該類通過(guò)exte...
    oWSQo閱讀 672評(píng)論 0 1
  • 這是16年5月份編輯的一份比較雜亂適合自己觀看的學(xué)習(xí)記錄文檔鲸伴,今天18年5月份再次想寫文章府蔗,發(fā)現(xiàn)簡(jiǎn)書還為我保存起的...
    Jenaral閱讀 2,767評(píng)論 2 9
  • 最無(wú)情的不是人姓赤,是時(shí)間;最珍貴的不是金錢仲吏,是情感不铆;最有力的不是老板蝌焚,是大自然;最可怕的不是災(zāi)難誓斥,是災(zāi)后無(wú)援只洒;最拿手...
    壹分鐘童話閱讀 1,507評(píng)論 0 0