美文网首页
super关键字

super关键字

作者: zhulichao | 来源:发表于2020-08-11 11:03 被阅读0次
    super关键字,既可以当作函数使用,也可以当作对象使用。使用super的时候,必须显式指定是作为函数、还是作为对象使用,否则会报错。由于对象总是继承其他对象的,所以可以在任意一个对象中,使用super关键字。
    
    ```
    class A {}
    class B extends A {
      constructor() {
        super();
        /*
        Uncaught SyntaxError: 'super' keyword unexpected here
        无法看出super是作为函数使用,还是作为对象使用
        */
        console.log(super);
        /*
        super.valueOf()表明super是一个对象
        */
        console.log(super.valueOf() instanceof B); // true
      }
    }
    
    var obj = {
      toString() {
        return "MyObject: " + super.toString();
      }
    };
    obj.toString(); // MyObject: [object Object]
    ```
    
    第一种情况,当作函数使用,代表父类的构造函数,super虽然代表了父类的构造函数,但是返回的是子类的实例,即super内部的this指的是子类。super()只能用在子类的构造函数中,用在其它地方就会报错。ES6要求,子类的构造函数必须执行一次super函数。
    
    ```
    class A{}
    class B extends A {
        constructor() {
            /*
            当作函数使用,代表父类的构造函数,相当于
            A.prototype.constructor.call(this)
            */
            super();
        }
    }
    ```
    
    第二种情况,super作为对象时,在普通方法中指向父类的原型对象,在静态方法中指向父类。ES6规定,通过super调用父类的方法时,super会绑定子类的this。由于绑定子类的this,所以如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
    
    ```
    class A {
      constructor() {
        this.q = 2;
      }
      p() {
        return 2;
      }
      print() {
        /*
        通过B的super.print()虽然调用的是A.prototype.print(),但是A.prototype.print()会绑定子类B的this,相当于
        super.print.call(this)
        */
        console.log(this.q);
      }
    }
    class B extends A {
      constructor() {
        super();
        this.q = 3;
        /*
        当作对象使用,这是普通方法,super指向A.prototype,相当于
        A.prototype.p()
        q是父类A实例的属性,super.q就引用不到它
        */
        console.log(super.p()); // 2
        console.log(super.q); // undefined
      }
      subPrint() {
        super.print();
      }
    }
    let b = new B();
    b.subPrint(); // 3
    ```
    
    ```
    class Parent {
      static myMethod(msg) {
        console.log('static', msg);
      }
      myMethod(msg) {
        console.log('instance', msg);
      }
    }
    
    class Child extends Parent {
      static myMethod(msg) {
        // 静态方法,super指向父类
        super.myMethod(msg);
      }
      myMethod(msg) {
        // 普通方法,super指向父类的原型对象
        super.myMethod(msg);
      }
    }
    
    Child.myMethod(1); // static 1
    var child = new Child();
    child.myMethod(2); // instance 2
    ```

    相关文章

      网友评论

          本文标题:super关键字

          本文链接:https://www.haomeiwen.com/subject/enzdhktx.html