super 关键字,既可以当作函数使用,也可以当作对象使用。在这两种情况下,它的用法完全不同。

1、super当做函数使用

super 作为函数调用时,代表父类的构造函数。ES6 要求,子类的构造函数必须执行一次 super() 函数。注意:作为函数时,super() 只能用在子类的构造函数之中,用在其他地方就会报错。

  1. class A {}
  2. class B extends A {
  3. constructor() {
  4. super();
  5. }
  6. }

super 作为函数调用时,内部的 this 指的是子类实例

复制代码
  1. class A {
  2. constructor() {
  3. this.show();
  4. }
  5. }
  6. class B extends A {
  7. constructor() {
  8. super();
  9. }
  10. show(){
  11. console.log('实例');
  12. }
  13. static show(){
  14. console.log('子类');
  15. }
  16. }
  17. new B()  //输出 '实例' ,new B 时触发了 B 的构造函数,所以触发了 super 方法,即触发了父类 A 的构造函数,此时的 this.show 的 this 指的是子类
复制代码

 

2、super 作为对象使用

super 作为对象时,在普通方法中,指向父类的原型对象;在静态方法中,指向父类。

2.1、super在普通方法中(即非静态方法)及此时的 this 关键字指向

复制代码
  1. class A {
  2. p() {
  3. return 2;
  4. }
  5. }
  6. class B extends A {
  7. constructor() {
  8. super();
  9. console.log(super.p()); // 2 此时的super指向父类原型对象,即 A.prototype
  10. }
  11. }
  12. let b = new B();  //2
复制代码

由于在普通方法中的 super 指向父类的原型对象,所以如果父类上的方法或属性是定义在实例上的,就无法通过 super 调用的。如下所示:

复制代码
  1. class A {
  2. constructor() { //在构造函数上定义的属性和方法相当于定义在父类实例上的,而不是原型对象上
  3. this.p = 2;
  4. }
  5. }
  6. class B extends A {
  7. get m() {
  8. return super.p;
  9. }
  10. }
  11. let b = new B();
  12. console.log(b.m) // undefined
复制代码

 

在子类普通方法中通过 super 调用父类的方法时,方法内部的 this 指向的是当前的子类实例。

复制代码
  1. class A {
  2. constructor() {
  3. this.x = 1;
  4. }
  5. print() {
  6. console.log(this.x);
  7. }
  8. }
  9. class B extends A {
  10. constructor() {
  11. super();
  12. this.x = 2;
  13.    super.y = 123;  //如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
  14. }
  15. m() {
  16. super.print();
  17. }
  18. }
  19. let b = new B();
  20. b.m() // 2
  21. console.log(b.y); //123
复制代码

 

2.2、super在静态方法中及此时的 this 关键字指向

super作为对象,用在静态方法之中,这时 super 将直接指向父类,而不是父类的原型对象。

复制代码
  1. class Parent {
  2. static myMethod(msg) {
  3. console.log('static', msg);
  4. }
  5. myMethod(msg) {
  6. console.log('instance', msg);
  7. }
  8. }
  9. class Child extends Parent {
  10. static myMethod(msg) {
  11. super.myMethod(msg);
  12. }
  13. myMethod(msg) {
  14. super.myMethod(msg);
  15. }
  16. }
  17. Child.myMethod(1); // static 1
  18. var child = new Child();
  19. child.myMethod(2); // instance 2
复制代码

在子类的静态方法中通过 super 调用父类的方法时,方法内部的 this 指向当前的子类,而不是子类的实例。

复制代码
    1. class A {
    2. constructor() {
    3. this.x = 1;
    4. }
    5. static print() {
    6. console.log(this.x);
    7. }
    8. }
    9. class B extends A {
    10. constructor() {
    11. super();
    12. this.x = 2;
    13. }
    14. static m() {
    15. super.print();
    16. }
    17. }
    18. B.x = 3;
    19. B.m() // 3
复制代码
posted on   ygunoil  阅读(570)  评论(0编辑  收藏  举报
编辑推荐:
· AI与.NET技术实操系列:基于图像分类模型对图像进行分类
· go语言实现终端里的倒计时
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
阅读排行:
· 25岁的心里话
· 闲置电脑爆改个人服务器(超详细) #公网映射 #Vmware虚拟网络编辑器
· 零经验选手,Compose 一天开发一款小游戏!
· 通过 API 将Deepseek响应流式内容输出到前端
· AI Agent开发,如何调用三方的API Function,是通过提示词来发起调用的吗
历史上的今天:
2020-08-17 react组件通信方式总结
< 2025年3月 >
23 24 25 26 27 28 1
2 3 4 5 6 7 8
9 10 11 12 13 14 15
16 17 18 19 20 21 22
23 24 25 26 27 28 29
30 31 1 2 3 4 5
点击右上角即可分享
微信分享提示