浅谈: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 欢迎大神批评指正!感激不尽!!!!!!