阿西河

所有教程

公众号
🌙
阿西河前端的公众号

我的收藏

    最近访问  (文章)

      教程列表

      抓包专区
      测试专区

      JS super 运算符

      功能

      super 关键字用于访问和调用一个对象的父对象上的函数。

      super.propsuper[expr]表达式在类和对象字面量任何方法定义中都是有效的。

      语法

      super([arguments]);
      // 调用 父对象/父类 的构造函数
      
      super.functionOnParent([arguments]);
      // 调用 父对象/父类 上的方法
      

      描述

      在构造函数中使用时,super关键字将单独出现,并且必须在使用 this 关键字之前使用。super关键字也可以用来调用父对象上的函数。

      示例

      在类中使用 super

      以下代码片段来自于 classes sample。

      class Polygon {
        constructor(height, width) {
          this.name = 'Polygon';
          this.height = 1;
          this.width = 1;
        }
        sayName() {
          console.log('Hi, I am a ', this.name + '.');
        }
      }
      
      class Square extends Polygon {
        constructor(width,height) {
          this.height;
          // ReferenceError,super 需要先被调用!
      
      /*
         这里,它调用父类的构造函数的,
         作为Polygon 的 width
          super(length, length);
      
      /*
          注意: 在派生的类中, 在你可以使用'this'之前, 必须先调用super()。
          忽略这, 这将导致引用错误。
      */
          this.name = 'Square';
        }
      
        get area() {
          return this.height * this.width;
        }
      
        set area(value) {
          this.area = value;
        }
      }
      var fn = new Polygon(1,2)
      

      调用父类上的静态方法

      你也可以用 super 调用父类的静态方法。

      class Rectangle {
        constructor() {}
        static logNbSides() {
          return 'I have 4 sides';
        }
      }
      
      class Square extends Rectangle {
        constructor() {}
        static logDescription() {
          return super.logNbSides() + ' which are all equal';
        }
      }
      Square.logDescription(); // 'I have 4 sides which are all equal'
      

      删除 super 上的属性将抛出异常

      你不能使用 delete 操作符 加 super.prop 或者 super[expr] 去删除父类的属性,这样做会抛出 ReferenceError。

      class Base {
        constructor() {}
        foo() {}
      }
      class Derived extends Base {
        constructor() {}
        delete() {
          delete super.foo;
        }
      }
      
      new Derived().delete();
      // ReferenceError: invalid delete involving 'super'.
      

      Super.prop 不能覆写不可写属性

      当使用 Object.defineProperty 定义一个属性为不可写时,super 将不能重写这个属性的值。

      class X {
        constructor() {
          Object.defineProperty(this, 'prop', {
            configurable: true,
            writable: false,
            value: 1
          });
        }
      }
      
      class Y extends X {
        constructor() {
          super();
        }
        foo() {
          super.prop = 2;   // Cannot overwrite the value.
        }
      }
      
      var y = new Y();
      y.foo(); // TypeError: "prop" is read-only
      console.log(y.prop); // 1
      

      在对象字面量中使用 super.prop

      Super 也可以在 object initializer / literal 符号中使用。在下面的例子中,两个对象各定义了一个方法。在第二个对象中, 我们使用 super 调用了第一个对象中的方法。 当然,这需要我们先利用 Object.setPrototypeOf() 将 obj2 的原型加到 obj1 上,然后才能够使用 super 调用 obj1 上的 method1。

      var obj1 = {
        method1() {
          console.log("method 1");
        }
      }
      
      var obj2 = {
        method2() {
         super.method1();
        }
      }
      
      Object.setPrototypeOf(obj2, obj1);
      obj2.method2();
      // logs "method 1"
      

      规范

      SpecificationStatusComment
      ECMAScript 2015 (6th Edition, ECMA-262)
      super
      StandardInitial definition.
      ECMAScript Latest Draft (ECMA-262)
      super
      Draft
      目录
      目录