浅谈:es6 super

es6里面class的继承这一章, 对super一些概念上的理解,通过查询网上大神们的见解,来加深自己的理解:

class A {

  constructor() {

    this.x = 1;

  }

}

class B extends A {

  constructor() {

    super();

    this.x = 2;

    super.x = 3;

    console.log(this.x); // 3

  }

}

let b = new B();

解析:由于this指向子类实例,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
上面代码中,super.x赋值为3,这时等同于对this.x赋值为3!

深入理解:

super作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

ES6 规定,在子类普通方法中通过super调用父类的方法时,方法内部的this指向当前的子类实例。

这两句话连在一起,不矛盾!意思就是:

意思是:

在子类普通方法中通过super调用父类的方法时

super指向父类的原型对象,但是父类的方法中的this指向当前的子类实例。

super.x = 3;

这里super指向父类的原型对象,没错!

但是底层并不是直接执行

A.prototype.x = 3

而是转换了底层的this,最终效果类似于:

this = 3

代码验证:

class A {

  constructor() {

    this.x = 1

  }

}

class B extends A {

  constructor() {

    super()

    this.x = 2

    Object.defineProperty(A.prototype, 'x', {

      set: function(val) {

        console.log(this, val)

         //B {x: 2} 3,证明对super的赋值最终作用到了B {x: 2}身上,也就是新生成的实例,this

      }

    })

    super.x = 3

    console.log(this.x) // 3

  }

}

let b = new B()

你再看看阮老师举的函数调用的例子,这个例子就更清楚了,因为函数可以用 call

代码:

class A {

  constructor() {

    this.x = 1

  }

  print() {

    console.log(this.x)

  }

}

class B extends A {

  constructor() {

    super()

    this.x = 2

  }

  m() {

    // super.print()//上下两句等价的,所以上面这句隐含转换了this

    super.print.call(this)

  }

}

let b = new B()

b.m() // 2

super.print() 等价于super.print.call(this),因为底层隐含转换了this

所以,最终有了下面的解释:

由于this指向子类实例,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。

 

ps  欢迎大神批评指正!感激不尽!!!!!!

posted on 2020-06-07 13:05  文艺小书生  阅读(525)  评论(0编辑  收藏  举报

导航