首页 > 建站教程 > JS、jQ、TS >  js中的super正文

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

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