文章來源阮一峰ES6入門,這里做要點掌握大綱。
class——構(gòu)造函數(shù)的語法糖
ES5的繼承:修改原型鏈
先創(chuàng)造子類的實例對象,再將父類的方法添加到this(Parent.apply(this) )
ES6的繼承:通過extends實現(xiàn)繼承
先將父類實例 的屬性方法加到this上(super),然后再用子類的構(gòu)造函數(shù)修改this
- super
- 子類必須在構(gòu)造函數(shù)中調(diào)用super方法,用來創(chuàng)建父類的this對象。因為子類this通過父類構(gòu)造函數(shù)塑造,得到和父類一樣的實例屬性和方法(實例屬性和類的本身屬性參考上一節(jié)class的基本語法。)不調(diào)用super,子類就得不到this。
在子類的構(gòu)造函數(shù)中,只有調(diào)用super之后才可以使用this 關(guān)鍵字,因為super 之后子類才有了自己的this。 - super關(guān)鍵字可以當函數(shù)使用也可以當對象使用。用法不同。必須顯示指定super的數(shù)據(jù)類型
class A {}
class B extends A {
constructor() {
super();
console.log(super.valueOf() instanceof B); // true,valueOf()返回該對象的原始值。
}
}
let b = new B();
作為函數(shù)使用時,代表父類的構(gòu)造函數(shù),只能在子類構(gòu)造函數(shù)中使用,super內(nèi)部的this指向子類實例。
class A {
constructor() {
console.log(new.target.name);
}
}
class B extends A {
constructor() {
super();
}
}
new A() // A
new B() // B
作為對象使用時,在靜態(tài)方法中指向父類,在普通方法中,指向父類原型對象。
注意:super指向父類的原型對象,而不是父類實例,所以父類實例上的屬性方法無法通過super調(diào)用。(父類構(gòu)造函數(shù)里this調(diào)用的屬性方法就是實例屬性方法)
class A {
constructor() {
this.p = 2;
}
}
class B extends A {
get m() {
return super.p;
}
}
let b = new B();
b.m // undefined
定義在父類實例上的屬性應(yīng)該是這樣子
class A {}
A.prototype.x = 2;
class B extends A {
constructor() {
super();
console.log(super.x) // 2
}
}
let b = new B();
在普通方法中使用super 對象時, 方法內(nèi)部的this指向當前的子類實例
class A {
constructor() {
this.x = 1;
}
print() {
console.log(this.x);
}
}
class B extends A {
constructor() {
super();
this.x = 2;
}
m() {
super.print();
}
}
let b = new B();
b.m() // 2
對象總是繼承自另一個對象,所以可以在任意一個對象里使用super
var obj = {
toString() {
return "MyObject: " + super.toString();
}
};
obj.toString(); // MyObject: [object Object]
- 子類的構(gòu)造方法如果沒有寫也會被自動添加。
- 子類的實例也是父類的實例
let cp = new ColorPoint(25, 8, 'green');
cp instanceof ColorPoint // true
cp instanceof Point // true
- 父類的static 方法會被子類繼承
去class基本語法里會看到靜態(tài)方法(屬性)和私有方法(屬性)的使用方法
靜態(tài)方法只能直接通過類調(diào)用,但不能被實例繼承,變量名:static variable
私有方法只能在類內(nèi)部使用 ,變量名:#variable - 判斷一個類是否繼承了另一個類
Object.getPrototypeOf()可以獲取子類的父類
Object.getPrototypeOf(child) === parent
// true
- 類的prototype屬性和proto屬性
大多數(shù)瀏覽器的 ES5 實現(xiàn)之中,每一個對象都有proto屬性,指向?qū)?yīng)的構(gòu)造函數(shù)的prototype屬性。Class 作為構(gòu)造函數(shù)的語法糖,同時有prototype屬性和proto屬性,因此同時存在兩條繼承鏈。
(1)子類的proto屬性,表示構(gòu)造函數(shù)的繼承,總是指向父類。
(2)子類prototype屬性的proto屬性,表示方法的繼承,總是指向父類的prototype屬性。
我知道這張圖可能不準確,但是這樣記能讓我一下子找到對應(yīng)關(guān)系。

image.png
- 子類原型的原型是父類的原型,emm
var p1 = new Point(2, 3);
var p2 = new ColorPoint(2, 3, 'red');
p2.__proto__ === p1.__proto__ // false
p2.__proto__.__proto__ === p1.__proto__ // true

image.png
這里有個作用就是通過子類的實例可以修改父類的實例
子類實例.proto.proto.attr = whatever;,修改父類,進而音箱父類的實例。
- 原生構(gòu)造函數(shù)的繼承
原生構(gòu)造函數(shù),是指語言內(nèi)置的構(gòu)造函數(shù),用來生成數(shù)據(jù)結(jié)構(gòu),ES的構(gòu)造函數(shù)有9種:
Boolean(),String(),Number(),
Object(),Array(),Function(),
Date(),RegExp(),Error(),
后面的我就不想寫了...