前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
AI 篇
原理篇
每日一题
小程序题库
知识卡片
  • 场景篇按分类整理的大前端场景考点
  • 历年面经按年份追踪真实考点
  • 算法题库NEW在线编码即时判题
  • 专项自测100 题快速查漏
  • 前端基础
    • HTTP从报文一路讲到 HTTPS
    • 浏览器渲染、事件循环、进程
    • 计算机基础Linux、网络、操作系统
  • 进阶专项
    • 设计模式23 种模式怎么用
    • 前端系统进阶学习大型项目工程化
    • 前端综合文章长期沉淀的实践文
  • 工程与工具
    • Node学习指南从环境搭建到服务端
    • NPM工作流script、依赖与发布
    • Docker容器化部署上手
    • Canvas图形与动画实战
  • 路线与导图
    • 思维导图知识点全景图
    • 学习路线按图索骥不跑偏
  • 动态
    • 公众号动态公众号历史文章
    • 博客动态站长的技术博客
    • 开发者导航常用工具与文档站
  • AI 助手随时提问,即时解析
  • AI 模拟面试模拟真实面试 + 报告
  • AI 知识地图串起全站知识点
  • AI 定制路线按你的简历现排
AI 热点
旧版
首页程序员面试题库class 构造器 super this 绑定顺序
JavaScript对象与原型

在 ES6 class 的构造器中必须先调用 super() 吗?为什么?

派生类构造器要先调用 super(),才能访问 this;子类字段也会在这次调用返回后初始化。少见的例外是直接返回另一个对象,这时不使用本次创建的实例,也可以不调用 super()。

前端进阶之旅 · 一题精讲更新于 2026.09.29
JavaScript#对象与原型
先看核心答案读代码示例
理解线索

`super()` 与 `this` 的初始化顺序

  1. super()调用父类构造器,让派生类拿到可用的实例
  2. 子类字段在 super() 返回后、剩余构造器语句之前初始化
  3. 返回对象可代替实例作为构造结果,不必访问 this

显式返回对象可以绕开 super(),但继承来的初始化逻辑也随之跳过。

核心回答

先记住这个答案

派生类构造器要先调用 super(),才能访问 this。super() 执行父类构造器,返回后才轮到子类字段初始化,然后继续执行剩余构造器语句。显式构造器如果不调用 super(),又试图访问 this 或隐式返回实例,就会抛 ReferenceError。但如果直接返回另一个对象,可以不调用 super();这是少见的例外。

  • 派生类访问 this 前必须调用 super()
  • 子类字段在 super() 返回后初始化
  • 直接返回别的对象可以不调用 super()

super() 与 this 绑定的底层顺序

在派生类中,new 执行时先运行构造器中 super() 之前的代码,此时 this 尚未创建,任何对 this 的读取或赋值都会触发 ReferenceError。随后执行 super(),它调用父类构造器并创建实例对象,返回后 this 才可被访问。之后才初始化本类字段,再执行构造函数体剩余部分。

字段初始化器(如 field = 1)会在 super() 返回后按声明顺序执行。在 super() 之前尝试读取任何 this.field,先碰到的就是未初始化的 this 所导致的 ReferenceError,并不会先得到 undefined。这也是判断报错原因时最容易弄错的一步。

观察字段初始化位置JavaScript
class Base {
  constructor() {
    console.log('Base constructor, this has:', JSON.stringify(this));
  }
}

class Derived extends Base {
  fieldA = 'a';
  constructor() {
    super(); // 必须先调用 super
    console.log('After super, fieldA =', this.fieldA);
  }
}

new Derived();
查看输出与解释
Base constructor, this has: {}
After super, fieldA = a

在 Base 构造器中 this 还没有任何字段,因为 Derived 的字段要在 super() 返回后初始化,说明顺序是先创建 this,再初始化子类字段。

继承日志类必须遵守的调用顺序

现有 Logger 基类,构造器接收 level 并生成 timestamp;FileLogger 继承它并需要 filename。在 FileLogger 构造器里,若把 this.filename = filename 放在 super(level) 之前,运行时立刻抛 ReferenceError,无法创建实例。正确顺序是先 super(level),再设置子类特有属性。

这种强制顺序的工程价值在于:父类构造器中可能调用类方法或访问公共字段,如果子类字段抢先初始化,会使父类操作看到不完整的数据。super() 先行确保父类基础状态就绪,子类再增强,最终对象状态一致。碰到类似继承时,养成先 super 再操作 this 的习惯,能避免大多数初始化陷阱。

哪些情况不要求显式调用 super()

若派生类完全没有写构造器,语言会自动提供默认构造器,它内部调用 super(...args),因此无需显式书写。显式定义构造器后,如果要使用或返回正常的子类实例,就要调用一次 super();同一次构造过程中重复调用也会抛异常。

还有一个少见但真实的例外:派生类构造器可以不调用 super(),直接 return {}。返回对象会成为 new 的结果,未初始化的 this 不再需要返回,因此不会抛错。不过这样父类构造器和子类实例字段都没有在通常的实例上完成初始化,返回对象也未必在子类的原型链上。普通继承代码仍应先调用 super()。

回答前,多想一步

容易答错的地方

认为基类也要调用 super(),或只有访问 this 才需要 super
基类没有父类,调用 super() 语法本身就不存在。派生类如果既不读取 this,也不返回别的对象,漏掉 super() 仍会在隐式返回时抛 ReferenceError。直接返回对象的例外不能概括成“所有显式构造器都必须调用”。
认为 super() 必须放在第一行,或用 super 只能调用父类方法
super() 可以在访问 this 之前的任何位置,比如在局部声明后调用;它用于调用父类构造器,而 super.method() 才访问父类原型方法。两者书写位置和语法不同,不能混为一谈。
试着用自己的话回答

面试官还会怎么问?

在子类构造器中,如果我不引用 this,仅做参数校验,还需要调用 super() 吗?

如果还要返回正常的子类实例,仍然需要。参数校验可以放在 super() 之前,只要这段代码不访问 this。若校验失败直接抛错,也无需继续调用;若直接返回另一个对象,则属于少见的替换实例路径。

super() 调用前能读取类中声明的字段吗?

不能。在 super() 前,this 本身还没有初始化;读取 this.field 会先抛 ReferenceError,不会返回 undefined。super() 返回后,子类字段初始化器才依次执行,随后构造器剩余语句才能读到它们。

super() 之前能调用父类方法吗?

不能通过 this.method() 调用,因为读取 this 就会抛 ReferenceError。super.method() 的属性查找可能成功,但常规实例方法往往还要使用接收者 this;在实例初始化前调用它同样不可靠。先 super(),再调用需要实例状态的方法。

从一道题,走向一组知识

把知识连起来

对象与原型

构造函数返回对象或原始值时,new 最后会得到什么?

子类显式返回对象能绕开 super();另一题解释返回对象怎样覆盖默认实例。

对象与原型

属性设成 enumerable:false 后,for...in 和 Object.keys 还能遍历到吗?

子类字段初始化后会成为实例的自有属性,另一题进一步讨论属性能否被枚举。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • constructor

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. super() 与 this 绑定的底层顺序
  3. 继承日志类必须遵守的调用顺序
  4. 哪些情况不要求显式调用 super()
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑