class的實現(xiàn)
- class對象內(nèi)部的constructor及其方法踏枣,是作為構(gòu)造器原型上的屬性存在的颈抚,這也是我們說class是構(gòu)造函數(shù)語法糖的原因蝌借,但是實際上class定義的函數(shù)衙传,擁有特殊屬性classConstructor嘱支,且不可枚舉(這與es5不同)蚓胸,默認(rèn)嚴(yán)格模式
- 默認(rèn)調(diào)用constructor函數(shù),生成子類的this并返回除师,除非顯式的定義在this(或者放在頂層)上否則所有屬性都掛在原型上
- 內(nèi)部的this指向構(gòu)造出來的實例沛膳,對于靜態(tài)方法則指向class不被實例繼承,可以被子類繼承汛聚,通過super調(diào)用
- new.target 實例通過new 或constructor 構(gòu)造會返回構(gòu)造函數(shù)名锹安,子類的繼承時會返回子類名(寫出只有繼承才能使用的類)
- 沒有變量提升,為了保證聲明和繼承的順序
class Animal {
constructor(name) {
this.speed = 0;
this.name = name;
}
run(speed) {
this.speed = speed;
alert(`${this.name} runs with speed ${this.speed}.`);
}
stop() {
this.speed = 0;
alert(`${this.name} stands still.`);
}
}
let animal = new Animal("My animal");
Class的繼承
- 與ES5通過先創(chuàng)建子類的this對象倚舀,再將父類的方法通過call/apply添加到this上叹哭,最后返回子類的這種實現(xiàn)方式不同;
- extend關(guān)鍵字繼承時痕貌,期望通過調(diào)用父類(非繼承)的constructor來實現(xiàn)this的創(chuàng)建风罩,所以需要super來完成這個過程,因此芯侥,派生的 constructor 必須調(diào)用 super 才能執(zhí)行其父類(非派生的)的 constructor泊交,否則 this 指向的那個對象將不會被創(chuàng)建。并且我們會收到一個報錯柱查。繼承后的實例查找過程類似原型查找
- super作為函數(shù)只能在constructor中調(diào)用廓俭,作為對象調(diào)用時:普通方法中調(diào)用super指向父類的原型,
賦值時等同this
唉工,內(nèi)部的this指向子類構(gòu)造出來的實例研乒;靜態(tài)方法里調(diào)用super則指向父類,內(nèi)部的this指向子類(因為靜態(tài)方法不能被實例繼承) - 通過extend可以繼承原生構(gòu)造函數(shù) 淋硝,而es5中使用.call()寫法雹熬,無法繼承原生構(gòu)造函數(shù),對于原生的屬性方法會忽略傳入的this值導(dǎo)致繼承不完全
class Rabbit extends Animal {
hide() {
alert(`${this.name} hides!`);
}
}
let rabbit = new Rabbit("White Rabbit");
rabbit.run(5); // White Rabbit runs with speed 5.
rabbit.hide(); // White Rabbit hides!
// 繼承關(guān)系
Object.setPrototypeOf = function (obj, proto) {
obj.__proto__ = proto;
return obj;
}
// 父類指向子類
class A {
}
class B extends A {
}
B.__proto__ === A // true
B.prototype.__proto__ === A.prototype // true
// 沒有繼承關(guān)系
class A {
}
A.__proto__ === Function.prototype // true
A.prototype.__proto__ === Object.prototype // true
// 實例的原型的原型指向父類的原型
var p1 = new Point(2, 3);
var p2 = new ColorPoint(2, 3, 'red');
Object.getPrototypeOf(ColorPoint) === Point // true
p2.__proto__ === p1.__proto__ // false
p2.__proto__.__proto__ === p1.__proto__ // true
通過super調(diào)用使用了一個新的屬性 [[HomeObject]] 他記住了對象的屬性谣膳,這個屬性必須要當(dāng)做對象的方法才能調(diào)用