es6的class關鍵字用于快速地定義“類”;class的本質(zhì)是function,它可以看作一個語法糖,讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法。提升class不存在變量提升,類的所有方法都定義在類的prototype屬性上面,在類的實例上面調(diào)用方法,其實就是調(diào)用原型上的方法。
前端(vue)入門到精通課程:進入學習
Apipost = Postman + Swagger + Mock + Jmeter 超好用的API調(diào)試工具:點擊使用
本教程操作環(huán)境:windows7系統(tǒng)、ECMAScript 6版、Dell G3電腦。
基礎
-
es6引入了Class(類)這個概念,class關鍵字用于快速地定義“類”。新的class寫法讓對象原型的寫法更加清晰、更像面向?qū)ο缶幊痰恼Z法,也更加通俗易懂。
-
實際上背后依然使用的 原型和構(gòu)造函數(shù)的概念。
-
嚴格模式 不需要使用use strict因為只要代碼寫在類和模塊內(nèi),就只能使用嚴格模式。
-
提升class不存在變量提升 (由于繼承有關 必須確保子類在父類之后定義)。
-
類的所有方法都定義在類的prototype屬性上面,在類的實例上面調(diào)用方法,其實就是調(diào)用原型上的方法 原型方法可以通過實例對象調(diào)用,但不能通過類名調(diào)用,會報錯
class 為es6用來定義一個類
-
實際上 class只是一個語法糖 是構(gòu)造函數(shù)的另一種寫法
-
(語法糖 是一種為避免編碼出錯 和提高效率編碼而生的語法層面的優(yōu)雅解決方案 簡單說 一種便攜寫法 而已)
看代碼
class Person{ } console.log(typeof Person) //funciton console.log(Person.prototype.constructor === Person) //true
使用看代碼
用法和使用 構(gòu)造函數(shù)一樣 通過new 來生成對象實例
class person2 { } let json = new person2;
屬性和方法
定義在constructor 內(nèi)的屬性和方法 即調(diào)用在this上 屬于實例屬性和方法 否則屬于原型屬性和方法
class Person { constructor (name) { this.name = name //constructor內(nèi)定義的方法和屬性是實例對象自己的, } say () { //而constructor外定義的方法和屬性則是所有實例對象可以共享的 注意! console.log('hello') } } let jon = new Person() jon.hasOwnPrototype('name') //true jon.hasOwnPrototype('say') //false
靜態(tài)方法
不需要通過實例對象,可以直接通過類來調(diào)用的方法,其中的 this 指向類本身
class Person { static doSay () { this.say() } static say () { console.log('hello') } } Person.doSay() //hello *********************************************************************************************** //靜態(tài)方法可以被子類繼承 class Sub extends Person { } Sub.doSay() // hello //靜態(tài)方法可以通過類名調(diào)用,不能通過實例對象調(diào)用,否則會報錯 class Person { static sum(a, b) { console.log(a + b) } } var p = new Person() Person.sum(1, 2) // 3 p.sum(1,2) // TypeError p.sum is not a function
name屬性
name 屬性返回了類的名字 即緊跟在class后面的名字。
class Person { } Person.name // Person
this 默認指向類的實例。
類的方法內(nèi)部如果含有this 坑兒 一但單獨使用該方法 很可能就會報錯
如果 this指向不對 1使用箭頭函數(shù) 2在構(gòu)造方法中綁定this
取值函數(shù)(getter)和存值函數(shù)(setter)
class Person { get name () { return 'getter' } set name(val) { console.log('setter' + val) } } let jon = new Person() jon.name = 'jon' // setter jon jon.name // getter
//類聲明不可以重復
class Person {}
class Person {}
// TypeError Identifier 'Person' has already been declared
constructor關鍵字
- constructor 方法
- constructor 方法是類的默認方法,通過 new 命令生成對象實例時,自動調(diào)用該方法(默認返回實例對象 this)。
- 一個類必須有 constructor 方法,如果沒有顯式定義,一個空的 constructor 方法會被默認添加。
- 一個類只能擁有一個名為 “constructor” 的特殊方法,如果類包含多個 constructor 的方法,則將拋出 一個 SyntaxError 。
class Person { constructor(x, y) { this.x = x //默認返回實例對象 this this.y = y } toString() { console.log(this.x + ', ' + this.y) } }
constructor 啥子?
每一個類必須要由一個constructor 如果沒有顯示聲明 js引擎會自動添加一個空的構(gòu)造函數(shù)
class person3 { } //等于 class person3 { constructor(){} }
注意 在類中聲明方法的時候,方法前不加 function 關鍵字 方法之間不要用逗號分隔,否則會報錯 類的內(nèi)部所有定義的方法,都是不可枚舉的(non-enumerable)
注意 與es5一樣 實例的屬性除非 顯示定義在其本身(即this對象)上 否則都是定義在原型上面
class Point { constructor(x,y){ this.x = x; this.y = y; } toString(){ return `this.x + this.y`; } } var point = new Point(); point.toString() //(2,3) point.hasOwnProperty("x") //true point.hasOwnProperty("y") //true 在這x&&y都是實例對象point自身的屬性(因為定義在this變量上) // 所以返回true point.hasOwnProperty("toString") //false toString是原型對象的屬性 (因為定義在Point類上) //所以返回false point._proto_.hasOwnProperty("toString") //true //加兩個實例 var p1 = new Point(); var p2 = new Point(); p1._proto_ === p2._proto_ //true 這個不建議使用 //上面代碼中 p1和p2 都是point的實例 他們的原型都是Point.prototype 所以 _proto_屬性是相等的 //即是說 可以通過實例的_proto_ 屬性為 "類" 添加方法
super關鍵字
super關鍵字用于訪問和調(diào)用 父類上的函數(shù),可以調(diào)用父類的構(gòu)造函數(shù) 也可以調(diào)用父類的普通函數(shù)
class Father { constructor (surname){ this.surname = surname } say(){ console.log("你的名字" + this.surname) //你的名字錘子 } } //在這里 子繼承父類 class Son extends Father { constructor(surname,name){ super(surname) this.name = name } say(){ super.say() console.log('調(diào)用普通' + this.name) //調(diào)用普通鐵的 } } var son = new Son('錘子',"鐵的") son.say() console.log(son) //打印 {surname: "錘子", name: "鐵的" //在子類的構(gòu)造函數(shù)如果使用 super 調(diào)用父類的構(gòu)造函數(shù) 必須寫在 this之前 //還可以 調(diào)用父類的普通方法 //在es6中 類沒變量提升 必須先定義 才能通過實例化對象類里面的 共有屬性 和方法 通過this 調(diào)用 //類 里面的this 代表什么 //constructor 里面this指向?qū)嵗龑ο? // 方法里面this 代表 方法的 調(diào)用者
extends繼承
繼承即子承父業(yè)現(xiàn)實中 程序中子類可以繼承父類中的一些 方法和屬性
繼承時面向?qū)ο蟮?一大特性 可以減少代碼的編寫 方便公共內(nèi)容的抽取 關鍵字extends
class Father { constructor (surname){ this.surname = surname } say(){ //父級Father里面有一個方法 say() console.log("你的名字" + this.surname) } } class Son extends Father { //在這里Son 繼承了 Father父級里面的方法 關鍵字extends } var son = new Son('錘子') //new 出來實例 son.say() //打印 你的名字錘子
類的方法
class Person { constructor(name, age) { // 構(gòu)造函數(shù),接收一個name和age this.name = name this.age = age } say(){ // 一個方法 //注意類里面的方法不加function關鍵字 方法與方法之間不用,號隔開 console.log("你好",this.name) } // ....sayWhat(){} saySome(){} } var person = new Person('老王',44) //調(diào)用方法 person.say() //老王 //在類的實例上調(diào)用方法 其實就是調(diào)用 原型上的方法
類的表達式
與函數(shù)一樣 calss 也可以使用表達式的形式定義 采用class表達式 可以寫出立即執(zhí)行的Class!!
注意與函數(shù)表達式類似 類表達式在他們被求值前也不能使用(即賦值變量 之前調(diào)用) 但 與函數(shù)定義不同 雖然函數(shù)聲明可以提升 但類不能
類表達式(類定義)
類表達式可以是被命名的或匿名的
匿名類
let Person = class { constructor(x, y) { this.x = x this.y = y } }
命名的類
let Person = class Person { constructor(x, y) { this.x = x this.y = y } } const Mycalss = class Me { getClassName(){ return Me.name; } }; //這里用 表達式(即賦值變量一個) //注意! 這個類的名字是Mycalss而不是 Me Me只在Class的內(nèi)部代碼可用 指代當前類 let inst = new Mycalss(); inst.getClassName() //Me Me.name //報錯 Me只在Class內(nèi)部有定義
采用class表達式 可以寫出立即執(zhí)行的Class!!
let person = new class { constructor(name) { this.name = this.name; } sayname(){ console.log(this.name); } }("常東東") //這段代碼中class是立即執(zhí)行的實例
補充案例
class Animal { //class定義了一個“類” constructor(){ this.type = 'animal' //有一個constructor方法,這就是構(gòu)造方法 //this關鍵字則代表實例對象 } //constructor內(nèi)定義的方法和屬性是實例對象自己的,而constructor外定義的方法和屬性則是所有實例對象可以共享的 注意! says(say){ console.log(this.type + ' says ' + say) } } let animal = new Animal() animal.says('hello') //animal says hello class Cat extends Animal { //通過extends關鍵字實現(xiàn)繼承 //定義了一個Cat類,該類通過extends關鍵字,繼承了Animal類的所有屬性和方法。 constructor(){ super() //super關鍵字 它指代父類的實例(即父類的this對象)子類必須在constructor方法中調(diào)用super方法,否則新建實例時會報錯。 this.type = 'cat' //這是因為子類沒有自己的this對象,而是繼承父類的this對象,然后對其進行加工。如果不調(diào)用super方法,子類就得不到this對象。 } } let cat = new Cat() cat.says('hello') //cat says hello
【