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"

规范

Specification Status Comment
ECMAScript 2015 (6th Edition, ECMA-262)
super
Standard Initial definition.
ECMAScript Latest Draft (ECMA-262)
super
Draft

浏览器兼容

Update compatibility data on GitHub
Desktop Mobile Server
Chrome Edge Firefox Internet Explorer Opera Safari Android webview Chrome for Android Firefox for Android Opera for Android Safari on iOS Samsung Internet Node.js
super Chrome Full support 42 Edge Full support 13 Firefox Full support 45 IE No support No Opera Full support Yes Safari Full support Yes WebView Android Full support 42 Chrome Android Full support 42 Firefox Android Full support 45 Opera Android Full support Yes Safari iOS Full support Yes Samsung Internet Android Full support 4.0 nodejs Full support Yes

Legend

Full support  
Full support
No support  
No support

相关链接