js中的super


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對象。

ES6 規定,在子類普通方法中通過super調用父類的方法時,方法內部的this指向當前的子類實例

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

 

 

 

 

 

---------------------
作者:TianyuCool
來源:CSDN
原文:https://blog.csdn.net/qq_35087256/article/details/82669618

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM