首页 > 专栏 > 前端 > 文章详情
ES6 的 class 中 super 当做对象时使用的注意事项 发布于:2021-03-13 12:20:39   来源:阮一峰   查看:7  讨论:0
class A {
    p(){
        return 2;//ES5规定,实例的属性除非定义到this,否则都是定义到了原型上
    }
}
class B extends A{
    constructor() {
        super();
        console.log(super.p());//相当于调用父类的原型属性:A.prototype.p()
    }
}
let b = new B();
上述代码中,子类B中的super.p()就是将super当做对象使用。那么应该指向父类的原型,也就是A.prototype.p()。
class A {
    p(){
        this.p = 333;
    }
}
class B extends A{
    constructor() {
        super();
        console.log(super.p());// undefined this无法指向实例
    }
}
let b = new B();
由于super指向父类的原型对象,所以定义在父类this实例上的方法或属性是无法通过super调用的。
class A {
    p(){
        this.p = 333;
    }
}
//等同于
class A{}
A.prototype.p = 333
迷惑点来了:ES6规定,通过super调用父类的方法时,super会绑定子类的this。
class A {
    constructor() {
        this.x = 1;
    }
    print(){
        console.log(this.x);
    }
}
class B extends A{
    constructor() {
        super();
        this.x = 2;
    }
    m() {
        super.print();// 相当于 super.print.call(this);
        console.log(this);//此时的this指向子类B。B {x: 2}

    }
}
let b = new B();
b.m();//2
加深印象,通过super调用父类方法时,super会绑定子类的this:
class A {}
class B extends A{
    constructor() {
        super();
        console.log(super.valueOf() instanceof B);// true
    }
}
let b = new B();
super.valueOf()表面super是一个对象,所以super绑定B的this,所以super.valueOf()返回的是一个B的实例。
var obj = {
    toString(){
        return "MyObject:" + super.toString();
    }
}
console.log(obj.toString());//MyObject[object object]
由于对象总是继承其他对象的,所以可以在任意一个对象中使用super关键字。

评论

  • 匿名