探討 JS 繼承的 class property 行為
Class A extends Component
1
2
3
4
5
6
7
8
9
10
11
12
| class A extends Component {
static color = "red";
counter = 0;
arrowOnClick = () => {
console.log("A arrowOnClick");
}
onClick(){
console.log("A onClick");
}
}
|
經由 Babel 轉譯後,class properties 都會被移到 constructor 內
1
2
3
4
5
6
7
8
9
10
11
12
13
14
| /* --- After Babel --- */
class A {
constructor() {
// class properties 都會被移到 constructor 內
this.counter = 0;
this.arrowOnClick = () => {};
}
onClick() {}
}
A.color = "red";
console.log(A.prototype);
// Console output: {constructor: ƒ, onClick: ƒ}
// 因尚未實例化,因為沒跑constructor,所以看不到 class properties !
|
多重繼承
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
| class B extends A {
arrowOnClick = () => {
super.arrowOnClick(); // error occurred !!
console.log("B arrowOnClick");
}
onClick(){
super.onClick();
console.log("B onClick");
}
}
console.log(B.prototype); //B extends A, we get prototype of a
// A {constructor: ƒ, onClick: ƒ}
console.log(B.prototype.__proto__);
// {constructor: ƒ, onClick: ƒ}
new B().arrowOnClick(); //error occurred!
new B().onClick();
/*
--- console output ---
A onClick (from line 8)
B onClick (from line 9)
*/
class C extends A {
arrowOnClick() { // never called!
super.onClick();
console.log("C onClick");
}
}
console.log(C.prototype);
// A {constructor: ƒ, arrowOnClick: ƒ}
console.log(C.prototype.__proto__);
// {constructor: ƒ, onClick: ƒ}
new C().arrowOnClick(); //'new C()' 會執行 A 的 constructor !
// A arrowOnClick
class D extends A {}
new D().arrowOnClick();
// A arrowOnClick
|
記錄一下。