1.this和super的區別:
-
this關鍵詞指向函式所在的當前物件
-
super指向的是當前物件的原型物件
2.super的簡單應用
const person = {
name:'jack'
}
const man = {
sayName(){
return super.name;
}
}
Object.setPrototypeOf( man, person );
let n = man.sayName();
console.log( n ) //jack
複製程式碼
3.super的另類實現
super.name
等同於
Object.getPrototypeOf(this).name【屬性】
等同於
Object.getPrototypeOf(this).name.call(this)【方法】
複製程式碼
4.super中的this指向(易混淆)
super.name指向的是原型物件person 中的name,但是繫結的this還是當前的man物件。
const person = {
age:'20多了',
name(){
return this.age;
}
}
const man = {
age:'18歲了',
sayName(){
return super.name();
}
}
Object.setPrototypeOf( man, person );
let n = man.sayName();
console.log( n ) //18歲了
複製程式碼
Object.getPrototypeOf(this).name指向的是person的name,繫結的this也是person
const person = {
age:'20多了',
name(){
return this.age;
}
}
const man = {
age:'18歲了',
sayName(){
return Object.getPrototypeOf(this).name();
}
}
Object.setPrototypeOf( man, person );
let n = man.sayName();
console.log( n ) //20多了
複製程式碼
Object.getPrototypeOf(this).name.call(this)指向的是person的name,不過通過call改變了函式的執行上下文,所以this指向的還是man
const person = {
age:'20多了',
name(){
return this.age;
}
}
const man = {
age:'18歲了',
sayName(){
return Object.getPrototypeOf(this).name.call(this)
}
}
Object.setPrototypeOf( man, person );
let n = man.sayName();
console.log( n ) //18歲了
複製程式碼
4.Class中的super
(1)Class中的 super(),它在這裡表示父類的建構函式,用來新建父類的 this 物件
super()相當於Parent.prototype.constructor.call(this)
class Demo{
constructor(x,y) {
this.x = x;
this.y = y;
}
customSplit(){
return [...this.y]
}
}
class Demo2 extends Demo{
constructor(x,y){
super(x,y);
}
customSplit(){
return [...this.x]
}
task1(){
return super.customSplit();
}
task2(){
return this.customSplit();
}
}
let d = new Demo2('hello','world');
d.task1() //["w", "o", "r", "l", "d"]
d.task2() //["h", "e", "l", "l", "o"]
複製程式碼
(2)子類沒有自己的this物件,而是繼承父親的this物件,然後進行加工。如果不呼叫super,子類就得不到this物件
class Demo2 extends Demo{
constructor(x,y){
this.x = x; //this is not defined
}
}
複製程式碼
ES5的繼承,實質上是先創造子類的例項物件this,然後再將父類的方法新增到this上(Parent.call(this)
).
ES6的繼承,需要先建立父類的this,子類呼叫super繼承父類的this物件,然後再加工。
如果子類沒有建立constructor,這個方法會被預設新增:
class Demo{
constructor(x) {
this.x = x;
}
}
class Demo2 extends Demo{}
let d = new Demo2('hello');
d.x //hello
複製程式碼
(3) super 在靜態方法之中指向父類,在普通方法之中指向父類的原型物件
class Parent {
static myMethod(msg) {
console.log('static', msg);
}
myMethod(msg) {
console.log('instance', msg);
}
}
class Child extends Parent {
static myMethod(msg) {
super.myMethod(msg);
}
myMethod(msg) {
super.myMethod(msg);
}
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2
複製程式碼