ES6 class
基本概念
類的方法都定義在原型上
類的方法是不可枚舉的
類必須使用 new 來調(diào)用(typeof class 名 === 'function') -> 所以說類是構(gòu)造函數(shù)的語法糖
類沒有變量提升
super 關(guān)鍵字
可以作為函數(shù)使用,也可以作為對象使用,其他方式使用 super 的時候會報錯 (PS: 直接 console.log(super))
為什么在子類的構(gòu)造函數(shù)中必須要調(diào)用父類的構(gòu)造函數(shù)呢?
答:在 ES5 中,繼承是先定義子類的 this,然后在子類構(gòu)造函數(shù)內(nèi)部通過父類構(gòu)造函數(shù)的 call、apply 方法,將父類的屬性和方法添加到子類的實例上;但是在 ES6 中的繼承,是先有父類的 this,然后在子類的構(gòu)造函數(shù)中修改父類餓 this,也就是說子類沒有自己的 this,需要繼承父類的 this 才行。
所以在使用 class 實現(xiàn)繼承的時候如果在子類內(nèi)部自己定義了構(gòu)造方法,那么必須要在 constructor 中使用 this 之前調(diào)用 super()函數(shù),否則在實例話子類的時候就會報錯
在子類的構(gòu)造函數(shù)中通過函數(shù)調(diào)用 super 代表的是父類的構(gòu)造函數(shù),調(diào)用 super,將相當(dāng)于執(zhí)行
Parent.prototype.constructor.call(this),返回子類的實例在子類的方法中調(diào)用通過對象調(diào)用 super,相當(dāng)于父類的原型對象,但是通過 super 調(diào)用父類的方法是,方法內(nèi)部的 this 指向子類實例
在子類中給 super 添加屬性,相當(dāng)于添加到子類實例上
原生構(gòu)造函數(shù)的繼承
Array、Object 等
使用構(gòu)造函數(shù)的形式是無法繼承原生的構(gòu)造函數(shù)的
原因是 call、apply、bind 方法是無法為原生構(gòu)造函數(shù)綁定 this 的,所以子類是無法拿到父類內(nèi)部的屬性和方法的;而 ES5 的繼承原理則是先有子類的 this 然后再通過父類的構(gòu)造函數(shù)來 apply、call 來將父類的屬性和方法添加到子類實例上
可以通過 class 的方式繼承原生的構(gòu)造函數(shù)
原因是,class 繼承的原理就是現(xiàn)有父類的 this,然后在子類的構(gòu)造函數(shù)中先調(diào)用 super 來繼承父類的 this,再修改父類的 this,所以它可以繼承原生構(gòu)造函數(shù)
class 的靜態(tài)屬性和靜態(tài)方法
在 class 內(nèi)部直接在屬性或者方法之前加上 static 關(guān)鍵字即可
靜態(tài)屬性和方法只能同通過類型來調(diào)用
在子類的靜態(tài)方法中可以通過 super 來調(diào)用父類的靜態(tài)方法
class Foo {
static classMethod() {
return 'hello';
}
}
class Bar extends Foo {
static classMethod() {
return super.classMethod() + ', too';
}
}
Bar.classMethod();
class 的 prototype 和__ptoto__
class A {}
class B extends A {}
此時就有
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
原因是 class 的繼承是通過下面的方式實現(xiàn)的
class A {}
class B {}
// B 的實例繼承 A的實例
Object.setPrototypeOf(B.protorype, A.prototype);
// B 繼承 A的靜態(tài)屬性
Object.setPrototypeOf(B, A)
Object.setPrototypeOf = function(obj, proto) {
obj.__proto__ = proto;
return obj;
}
new.target
new 是讓構(gòu)造函數(shù)生成實例的命令。ES6 為 new 指令引入了一個 new.target 屬性,它返回的是 new 關(guān)鍵字作用于的構(gòu)造函數(shù)。
如果函數(shù)不是通過 new 來調(diào)用的,則 new.target 的值就是 undefined