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

 

posted @ 2019-06-10 10:11  ryelqy  阅读(4038)  评论(0编辑  收藏  举报