ES6 class类关键字super

super关键字

在 JavaSCript 中,能通过 extends 关键字去继承父类

super 关键字在子类中有以下用法:

  • 当成函数调用 super()
  • 作为 "属性查询" super.prop 和 superexpr

super()

super 作为函数调用时,代表父类的构造函数。

ES6 要求,子类的构造函数必须执行一次 super() 函数。

注意:作为函数时,super() 只能用在子类的构造函数之中,用在其他地方就会报错。

javascript 复制代码
class A {}
class B extends A {
  constructor() {
    super();
  }
}

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

javascript 复制代码
class A {
  constructor() {
    this.print();
  }
  print(){
    console.log('这是A');
  }
}
class B extends A {
  constructor() {
    super();
  }
  print(){
    console.log('这是B');
  }
}
new B() // 这是B
javascript 复制代码
// 继承了A的print
class A {
  constructor() {
    this.print();
  }
  print(){
    console.log('这是A');
  }
}
class B extends A {
  constructor() {
    super();
  }
}
new B() // 这是A

super.prop

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

普通方法

这里的super指向父类原型对象,即 A.prototype

javascript 复制代码
class A {
  x = 2
  p() {
    return this.x;
  }
}
class B extends A {
  print(){
    console.log(super.p())
  }
}
const a = new B()
a.print() // 2

由于在普通方法中的 super 指向父类的原型对象,而A的CLASS写法其实是:

javascript 复制代码
function A() {
  this.x = 2;

}

A.prototype.print = function () {
  return this.x
};

所以我们能够在父类A的原型对象上找到print方法。那么如果是这样:

javascript 复制代码
class A {
  x = 2
}
class B extends A {
  print(){
    console.log(super.x)
  }
}
const a = new B()
a.print() // undefined

自2022年之后,实例属性现在除了可以定义在constructor()方法里面的this上面,也可以定义在类内部的最顶层。所以这里的x=2其实等同于constructor(){this.x = 2};

如果父类上的方法或属性是定义在实例上的,就无法通过 super 调用的

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

javascript 复制代码
class A {
  constructor() {
    this.x = 1;
  }
  print() {
    console.log(this.x);
  }
}
class B extends A {
  constructor() {
    super();
    this.x = 2;
   super.y = 123;  //如果通过super对某个属性赋值,这时super就是this,赋值的属性会变成子类实例的属性。
  }
  m() {
    super.print();
  }
}
let b = new B();
b.m() // 2
console.log(b.y);  //123

静态方法

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

javascript 复制代码
class Parent {
  static myMethod(msg) {
    console.log('static', msg);
  }
  myMethod(msg) {
    console.log('instance', msg);
  }
}
class Child extends Parent {
  static myMethod(msg) {
    super.myMethod(msg);
  }
  myMethod(msg) {
    super.myMethod(msg);
  }
}
Child.myMethod(1); // static 1
var child = new Child();
child.myMethod(2); // instance 2

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

javascript 复制代码
class A {
  constructor() {
    this.x = 1;
  }
  static print() {
    console.log(this.x);
  }
}
class B extends A {
  constructor() {
    super();
    this.x = 2;
  }
  static m() {
    super.print();
  }
}
B.x = 3;
B.m() // 3
相关推荐
Hyyy9 分钟前
Electron多进程
前端
光影少年35 分钟前
RN原生交互 & 桥接
前端·javascript·react native·react.js·前端框架
东风破_39 分钟前
React 状态更新为什么不是立即赋值?从 useState、状态快照到更新队列
前端
GuWenyue42 分钟前
踩坑无数!吃透useState 3个核心技巧,彻底解决状态旧值、性能卡顿问题
前端·javascript·react.js
无人生还44 分钟前
从 Vue3 到 React · 快速上手系列第 4 篇:条件渲染与列表渲染
前端·vue.js·react.js
颜进强1 小时前
从零搭建私人 RAG 实战:用 Markdown 沉淀技术决策与业务决策
前端·后端·ai编程
咩咩啃树皮1 小时前
第46篇:Vue3 Router工程化进阶——懒加载+嵌套路由+全局守卫+权限控制
javascript·vue.js·ecmascript
触底反弹1 小时前
💡 React 父子组件通信:一个进度条教会我的 5 件事
前端·react.js·面试
咩咩啃树皮1 小时前
第44篇:Vue3侦听器完全精讲——watch与watchEffect区别、深度监听、异步业务落地
前端·javascript·vue.js
Python私教1 小时前
前端转 AI 全栈:别只做聊天框,SSE 与审批流才是分水岭
前端·人工智能