15.es6中的類

1.使用class定義一個(gè)類:類的聲明類的表達(dá)式

//方法一:類的聲明
class Person {

}
//方法二:類的表達(dá)式
const Student = class {

}

console.log(Person.prototype) //{}
console.log(Object.getOwnPropertyDescriptors(Person.prototype))
// {
//   constructor: {
//     value: [class Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   }
// }
console.log(Person.prototype.__proto__)//[Object:null prototype] {}
console.log(Person.prototype.constructor) //[class Person]
console.log(typeof Person) //function

var p = new Person()
console.log(p.__proto__ === Person.prototype) //true

2.類的構(gòu)造函數(shù)

當(dāng)使用new 調(diào)用Person類創(chuàng)建一個(gè)對象時(shí)砚蓬,傳遞的參數(shù)如果傳遞給類?

class Person {
}
var p = new Person('小名', 30)
var s = new Person('小紅', 20)

通過new調(diào)用類傳遞的參數(shù)旦袋,會作為參數(shù)傳遞給類的構(gòu)造函數(shù)

定義類的時(shí)候,
如果沒有明確定義類的構(gòu)造方法,會使用類的默認(rèn)的構(gòu)造方法
如果明確定義了構(gòu)造方法酗宋,就使用定義的構(gòu)造方法
一個(gè)類只有一個(gè)構(gòu)造方法

// 定義類的時(shí)候,
// 如果沒有明確定義類的構(gòu)造方法疆拘,會使用類的默認(rèn)的構(gòu)造方法
// 如果明確定義了構(gòu)造方法蜕猫,就使用定義的構(gòu)造方法
// 一個(gè)類只有一個(gè)構(gòu)造方法

class Student {}

class Person {
  constructor(name, age) {
    this.name = name;
    this.age = age;
  }
}
console.log(Student.constructor); // [Function: Function] 輸出類的默認(rèn)構(gòu)造方法
console.log(Person.constructor); // [Function: Function]

var p = new Person("小名", 30);
var s = new Person("小紅", 20);
console.log(p.name, p.age); //小名 30
console.log(s.name, s.age); //小紅 20

當(dāng)使用new 調(diào)用類時(shí),會執(zhí)行類的構(gòu)造函數(shù)哎迄,
調(diào)用類時(shí)傳遞的參數(shù)回右,會作為參數(shù)傳給類的構(gòu)造函數(shù)

class Person {
  //constructor為類的構(gòu)造函數(shù)(構(gòu)造方法)
  //類的構(gòu)造函數(shù)被調(diào)用時(shí):
  //1.在內(nèi)存中創(chuàng)建一個(gè)新對象(空對象)var moni = {}
  //2.這個(gè)對象內(nèi)部的[[prototype]]原型對象會指向類的prototype原型對象  moni.__proto__ = Person.prototype
  //3.this指向這個(gè)對象 this = moni
  //4.執(zhí)行構(gòu)造函數(shù)內(nèi)部的代碼
  //5.如果構(gòu)造函數(shù)沒有返回非空對象隆圆,則返回創(chuàng)建出來的新對象 return moni
  constructor(name, age) {
    this.name = name
    this.age = age
  }
}


//當(dāng)使用new 調(diào)用類時(shí),會執(zhí)行類的構(gòu)造函數(shù)翔烁,
//調(diào)用類時(shí)傳遞的參數(shù)渺氧,會作為參數(shù)傳給類的構(gòu)造函數(shù)
var p = new Person('小名', 30)
var s = new Person('小紅', 20)

3.給類的prototype原型對象上添加方法

class Person {
  constructor(name, age) {
    //定義的屬性定義在類的實(shí)例上
    this.name = name;
    this.age = age;
  }

  //在類的prototype原型對象上添加方法,不可枚舉
  eatting() {
    console.log(this.name + " is eatting");
  }
}

var p = new Person("xiaoming", 30);
p.eatting(); //xiaoming is eatting

console.log(p); //Person { name: 'xiaoming', age: 30 }
console.log(Person.prototype); //{} 定義類時(shí),添加到類的prototype原型對象上的方法是不可枚舉的
console.log(Object.getOwnPropertyDescriptors(Person.prototype));
// {
//   constructor: {
//     value: [class Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   eatting: {
//     value: [Function: eatting],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   }
// }

相當(dāng)于下面:

function Person(name, age) {
    this.name = name;
    this.age = age;
}
Person.prototype.eatting = function () {
  console.log(this.name + " is eatting");
}

4.給類的prototype原型對象上添加訪問器方法

class Person {
  constructor(name, age) {
    //定義的屬性定義在類的實(shí)例上
    this.name = name;
    this._age = age;
  }

  //在類的prototype原型對象上添加方法,不可枚舉,被類的實(shí)例調(diào)用
  eatting() {
    console.log(this.name + " is eatting");
  }

  //在類的prototype原型對象上定義訪問器方法,不可枚舉,被類的實(shí)例調(diào)用
  get age() {
    return this.age;
  }
  set age(newVal) {
    this._age = newVal
  }


}

var p = new Person('xiaoming', 30)
p.eatting() //xiaoming is eatting

console.log(p) //Person { name: 'xiaoming', _age: 30 }
console.log(Person.prototype) // {}
console.log(Object.getOwnPropertyDescriptors(Person.prototype)) 
// {
//   constructor: {
//     value: [class Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   eatting: {
//     value: [Function: eatting],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   age: {
//     get: [Function: get age],
//     set: [Function: set age],
//     enumerable: false,
//     configurable: true
//   }
// }

5.class類中定義靜態(tài)方法

class Person {
  constructor(name, age) {
    //定義的屬性定義在類的實(shí)例上
    this.name = name;
    this.age = age;
  }

  //在類的prototype原型對象上添加方法,不可枚舉,被類的實(shí)例調(diào)用
  eatting() {
    console.log(this.name + " is eatting");
  }

  //在類上添加靜態(tài)方法蹬屹,不可枚舉侣背,被類本身調(diào)用
  static createPerson() {
    return new Person("甲", 30);
  }
}

var p = new Person("xiaoming", 30);
p.eatting(); //xiaoming is eatting

console.log(p); //Person { name: 'xiaoming', age: 30 }
console.log(Object.getOwnPropertyDescriptors(Person.prototype));
// {
//   constructor: {
//     value: [class Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   eatting: {
//     value: [Function: eatting],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
// }
console.log(Person); //[class Person]
console.log(Object.getOwnPropertyDescriptors(Person));
// {
//   length: { value: 2, writable: false, enumerable: false, configurable: true },
//   prototype: {
//     value: {},
//     writable: false,
//     enumerable: false,
//     configurable: false
//   },
//   createPerson: {
//     value: [Function: createPerson],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   name: {
//     value: 'Person',
//     writable: false,
//     enumerable: false,
//     configurable: true
//   }
// }
console.log(Person.createPerson()); //Person { name: '甲', age: 30 }

相當(dāng)于

function Person (name, age){
  this.name = name;
  this.age = age;
}
Person.prototype.eatting = function () {
    console.log(this.name + " is eatting");
  }
Person.createPerson = function () {
  return new Person("甲", 30);
}

6.class類中的繼承

子類如果實(shí)現(xiàn)了繼承,在子類構(gòu)造函數(shù)中訪問this或return之前必須通過super調(diào)用父類構(gòu)造函數(shù)

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

//子類如果實(shí)現(xiàn)了繼承慨默,在子類構(gòu)造函數(shù)中訪問this或return之前必須通過super調(diào)用父類構(gòu)造函數(shù)
class Student extends Person {
  constructor(name, age, address) {
    super(name, age);
    this.address = address;
  }
}

var stu = new Student('小名', 30, '北京') 
console.log(stu) //Student { name: '小名', age: 30, address: '北京' }
console.log(stu.__proto__)//Person {} 輸出結(jié)果為一個(gè)對象贩耐,屬于Person類
//因?yàn)閟tu.__proto__為Student.prototype,
//而Student.prototype為一個(gè)對象,此對象的__proto__原型對象為Person.prototype 
//所以Student.prototype為Person類的一個(gè)實(shí)例對象厦取,即stu.__proto__為一個(gè)Person類的一個(gè)實(shí)例對象
//stu的[[prototype]]原型對象為Person的實(shí)例潮太,為[[prototype]]原型對象為Person.prototype原型對象的對象
console.log(stu.__proto__.__proto__ === Person.prototype) //true

子類繼承父類的原型對象上的方法和子類繼承父類上的靜態(tài)屬性和方法

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

  running() {
    console.log(this.name + " is running");
  }
  static createPerson() {
    console.log("創(chuàng)建person");
  }
}

//子類如果實(shí)現(xiàn)了繼承,在子類構(gòu)造函數(shù)中訪問this或return之前必須通過super調(diào)用父類構(gòu)造函數(shù)
class Student extends Person {
  constructor(name, age, address) {
    super(name, age);
    this.address = address;
  }
  //在子類的原型對象上定義running方法
  eatting() {
    console.log(this.name + " is eatting");
  }

  //在子類上定義靜態(tài)方法
  static createStudent() {
    console.log("創(chuàng)建student");
  }
}

var stu = new Student("小名", 30, "北京");
console.log(stu); //Student { name: '小名', age: 30, address: '北京' }
stu.running(); //小名 is running
stu.eatting(); //小名 is eatting
Student.createStudent(); //創(chuàng)建student
Student.createPerson(); //創(chuàng)建person

console.log(stu.__proto__); //Person {} 為一個(gè)Person類的對象虾攻,即類Person的一個(gè)實(shí)例
console.log(Object.getOwnPropertyDescriptors(stu.__proto__));
// {
//   constructor: {
//     value: [class Student extends Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   eatting: {
//     value: [Function: eatting],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   }
// }
//定義子類時(shí)铡买,定義在子類prototype原型對象的方法,在子類的prototype對象上

console.log(stu.__proto__.__proto__); //{} 為父類Person類的prototype原型對象
console.log(stu.__proto__.__proto__ === Person.prototype); //true
console.log(Object.getOwnPropertyDescriptors(stu.__proto__.__proto__));
// {
//   constructor: {
//     value: [class Person],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   running: {
//     value: [Function: running],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   }
// }

// 定義子類時(shí)台谢,繼承的父類的prototype原型對象上的方法寻狂,依然在父類的prototype原型對象上



console.log(Student) //[class Student extends Person]
console.log(Object.getOwnPropertyDescriptors(Student))
// {
//   length: { value: 3, writable: false, enumerable: false, configurable: true },
//   prototype: {
//     value: Person {},
//     writable: false,
//     enumerable: false,
//     configurable: false
//   },
//   createStudent: {
//     value: [Function: createStudent],
//     writable: true,
//     enumerable: false,
//     configurable: true
//   },
//   name: {
//     value: 'Student',
//     writable: false,
//     enumerable: false,
//     configurable: true
//   }
// }
console.log(Student.__proto__ === Person) //true 
// 因?yàn)樽宇惖腫[prototype]]原型對象為父類Person,所以可以通過子類Student調(diào)用父類Person上的方法

類對父類方法的重寫
在子類定義prototype原型對象方法內(nèi)部,可以通過super調(diào)用父類的prototype對象朋沮,父類prototype對象上的方法內(nèi)部的this被綁定為子類prototype原型對象方法內(nèi)部的this
在子類定義靜態(tài)方法內(nèi)部蛇券,可以通過super調(diào)用父類

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

  running() {
    console.log(this.name + ' is running')
  }
  eatting() {
    console.log(this.name + ' is eatting')
  }
  static createPerson() {
    console.log('第一步')
  }
}

//子類如果實(shí)現(xiàn)了繼承,在子類構(gòu)造函數(shù)中訪問this或return之前必須通過super調(diào)用父類構(gòu)造函數(shù)
class Student extends Person {
  constructor(name, age, address) {
    super(name, age);
    this.address = address;
  }

  //子類對父類方法的重寫
  eatting() {
    console.log('今天吃的很飽')
  }
  //在子類的原型對象上定義running方法
  running() {
    //通過super調(diào)用父類的原型對象樊拓,從父類的原型對象上獲取running方法纠亚,
    //此方法執(zhí)行時(shí)。方法內(nèi)容的this被綁定為當(dāng)前作用域的this
    super.running()
    console.log(this.name + ' run fastest')
  }

  //在子類上定義靜態(tài)方法
  static createPerson() {
    //通過super獲取父類筋夏,調(diào)用父類上的靜態(tài)方法
    super.createPerson()
    console.log('第二步')
  }
}

var stu = new Student('小名', 30, '北京') 
console.log(stu) //Student { name: '小名', age: 30, address: '北京' }
stu.running() 
//小名 is running
//小名 run fastest

Student.createPerson()
// 第一步
// 第二步
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末蒂胞,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子条篷,更是在濱河造成了極大的恐慌骗随,老刑警劉巖,帶你破解...
    沈念sama閱讀 216,402評論 6 499
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件赴叹,死亡現(xiàn)場離奇詭異鸿染,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)乞巧,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 92,377評論 3 392
  • 文/潘曉璐 我一進(jìn)店門涨椒,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人,你說我怎么就攤上這事蚕冬∶饣” “怎么了?”我有些...
    開封第一講書人閱讀 162,483評論 0 353
  • 文/不壞的土叔 我叫張陵囤热,是天一觀的道長猎提。 經(jīng)常有香客問我,道長赢乓,這世上最難降的妖魔是什么忧侧? 我笑而不...
    開封第一講書人閱讀 58,165評論 1 292
  • 正文 為了忘掉前任,我火速辦了婚禮牌芋,結(jié)果婚禮上蚓炬,老公的妹妹穿的比我還像新娘。我一直安慰自己躺屁,他們只是感情好肯夏,可當(dāng)我...
    茶點(diǎn)故事閱讀 67,176評論 6 388
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著犀暑,像睡著了一般驯击。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上耐亏,一...
    開封第一講書人閱讀 51,146評論 1 297
  • 那天徊都,我揣著相機(jī)與錄音,去河邊找鬼广辰。 笑死暇矫,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的择吊。 我是一名探鬼主播李根,決...
    沈念sama閱讀 40,032評論 3 417
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼几睛!你這毒婦竟也來了房轿?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 38,896評論 0 274
  • 序言:老撾萬榮一對情侶失蹤所森,失蹤者是張志新(化名)和其女友劉穎囱持,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體焕济,經(jīng)...
    沈念sama閱讀 45,311評論 1 310
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡洪唐,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 37,536評論 2 332
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了吼蚁。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 39,696評論 1 348
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖肝匆,靈堂內(nèi)的尸體忽然破棺而出粒蜈,到底是詐尸還是另有隱情,我是刑警寧澤旗国,帶...
    沈念sama閱讀 35,413評論 5 343
  • 正文 年R本政府宣布枯怖,位于F島的核電站,受9級特大地震影響能曾,放射性物質(zhì)發(fā)生泄漏度硝。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,008評論 3 325
  • 文/蒙蒙 一寿冕、第九天 我趴在偏房一處隱蔽的房頂上張望蕊程。 院中可真熱鬧,春花似錦驼唱、人聲如沸藻茂。這莊子的主人今日做“春日...
    開封第一講書人閱讀 31,659評論 0 22
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽辨赐。三九已至,卻和暖如春京办,著一層夾襖步出監(jiān)牢的瞬間掀序,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,815評論 1 269
  • 我被黑心中介騙來泰國打工惭婿, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留不恭,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 47,698評論 2 368
  • 正文 我出身青樓审孽,卻偏偏與公主長得像县袱,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個(gè)殘疾皇子佑力,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 44,592評論 2 353

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

  • js常用的編程模式有面向過程編程和面向?qū)ο缶幊蹋?)面向過程編程“面向過程”(Procedure Oriented...
    xiexw閱讀 199評論 0 1
  • 文章首發(fā)于 個(gè)人博客 目錄 class 靜態(tài)方法 靜態(tài)屬性 繼承 super class class是一個(gè)語法糖式散,...
    IOneStar閱讀 1,650評論 0 1
  • 前言 先來復(fù)習(xí)一下原型對象,原型對象就相當(dāng)于一個(gè)公共的區(qū)域打颤,所有同一個(gè)類的實(shí)例都可以訪問到這個(gè)原型對象暴拄。當(dāng)我們訪問...
    獨(dú)善其身_1558閱讀 216評論 0 0
  • 簡介 類的由來 JavaScript 語言中,生成實(shí)例對象的傳統(tǒng)方法是通過構(gòu)造函數(shù)编饺。下面是一個(gè)例子乖篷。 上面這種寫法...
    IT楊閱讀 791評論 0 2
  • ES6中定義類.繼承以及對象的操作0712 1.定義類的不同 回顧一下以前學(xué)習(xí)的在ES6之前定義一個(gè)類(不明顯,和...
    煤球快到碗里來閱讀 438評論 0 0