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ù),會(huì)作為參數(shù)傳遞給類的構(gòu)造函數(shù)

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

// 定義類的時(shí)候,
// 如果沒有明確定義類的構(gòu)造方法,會(huì)使用類的默認(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í),會(huì)執(zhí)行類的構(gòu)造函數(shù),
調(diào)用類時(shí)傳遞的參數(shù),會(huì)作為參數(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]]原型對象會(huì)指向類的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í),會(huì)執(zhí)行類的構(gòu)造函數(shù),
//調(diào)用類時(shí)傳遞的參數(shù),會(huì)作為參數(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)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡書系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

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

友情鏈接更多精彩內(nèi)容