前端进阶之旅前端进阶之旅
基础篇
进阶篇
高频篇
精选篇
手写篇
面经篇
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 静态方法是否被子类继承
JavaScript对象与原型

class 的静态方法会被子类继承吗?子类里怎么调用父类的静态方法?

会。class Dog extends Animal 会把 Dog 本身的原型设成 Animal,所以 Dog.create() 找不到时会顺着原型链找到 Animal.create()。子类里可以用 super.create() 调父类的版本,静态方法里的 this 指向实际调用它的那个类。

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

`extends` 连了两条原型链

  1. 实例这条链Dog.prototype 的原型是 Animal.prototype,实例方法靠它继承
  2. 类本身这条链Dog 的原型是 Animal,静态方法和静态字段靠它继承
  3. 静态方法里的 this谁调用就是谁,Dog.create() 里的 this 是 Dog

静态字段也是顺着原型链读到的。在子类上执行 this.count++,不会改父类的值,而是在子类上新建一个同名属性,父类和子类从此各算各的。

核心回答

先记住这个答案

会被继承。class Dog extends Animal 做了两件事:一是让 Dog.prototype 的原型指向 Animal.prototype,这是实例方法能继承的原因;二是让 Dog 这个构造函数本身的原型指向 Animal,这就是静态方法能继承的原因。所以 Dog.create() 在 Dog 上找不到,会顺着原型链找到 Animal.create()。子类想在自己的静态方法里调父类版本,用 super.create()。静态方法里的 this 指向实际调用它的类,不一定是定义它的类。

  • extends 会建立子类构造器原型链
  • 静态方法里的 this 是调用它的那个类
  • 子类静态方法可用 super 调父类版本
  • 实例不能直接调用静态方法

一个工厂方法看清继承、super 和 this

静态方法最常见的用途是工厂方法。下面父类定义了 create,子类重写后又调了父类版本。

子类重写并调用父类静态方法JavaScript
class Animal {
  static count = 0
  static create(name) {
    this.count++ // this 是调用它的那个类
    return new this(name) // 用 this 创建,子类调用就创建子类实例
  }
  constructor(name) { this.name = name }
}
class Dog extends Animal {
  static create(name) {
    const dog = super.create(name) // 调父类的静态方法,this 仍是 Dog
    dog.kind = 'dog'
    return dog
  }
}

const d = Dog.create('Lucky')
console.log(d instanceof Dog, d.kind)
console.log(Object.getPrototypeOf(Dog) === Animal)
console.log(Animal.count, Dog.count, Object.hasOwn(Dog, 'count'))
console.log(typeof d.create)
查看输出与解释
true dog
true
0 1 true
undefined

Dog.create 里调 super.create(name),执行的是 Animal.create 的代码,但 this 仍然是 Dog,所以 new this(name) 创建的是 Dog 实例。父类写工厂方法时用 new this() 而不是 new Animal(),子类就能直接复用。 第三行是个陷阱。this.count++ 先读 Dog.count,Dog 自己没有,顺着原型链读到 Animal.count 的 0,然后赋值 Dog.count = 1。赋值不会沿原型链去改父类,而是在 Dog 身上新建了一个 count。所以父类还是 0,子类变成了 1,而且是子类自己的属性。想让所有子类共用一个计数,要明确写 Animal.count++。 最后一行说明实例拿不到静态方法。实例的原型链是 Dog.prototype、Animal.prototype、Object.prototype,静态方法在 Dog 和 Animal 本身上,不在这条链里。

用 ES5 的写法理解它

在 class 之前,静态方法就是直接挂在构造函数上的属性,比如 Animal.create = function () {}。用 ES5 实现继承时,大多数人只写了 Dog.prototype = Object.create(Animal.prototype),静态方法是继承不过来的,需要再补一句 Object.setPrototypeOf(Dog, Animal)。

extends 相当于这两句都帮你写了。这也是为什么 Babel 编译 class 继承时,生成的辅助函数里会有一步设置子类构造函数原型的操作。

回答前,多想一步

容易答错的地方

以为静态方法里的 this 固定是定义它的类
this 看调用方式。Dog.create() 调用时 this 是 Dog。如果把方法取出来单独调用,比如 const fn = Dog.create; fn(),this 就是 undefined,class 内部是严格模式,new this() 会直接报错。
以为子类修改静态字段会影响父类
正好相反。子类赋值会在自己身上创建同名属性,父类不受影响。只有子类还没有自己的同名属性时,读取才会拿到父类的值。
以为私有静态字段也能被子类继承
static #total 只存在于 Animal 身上。父类静态方法里写 this.#total,如果通过 Dog.method() 调用,this 是 Dog,而 Dog 没有这个私有字段,会抛 TypeError。这种情况要写成 Animal.#total。
试着用自己的话回答

面试官还会怎么问?

实例方法里怎么调静态方法?

用 this.constructor.create(),它会找到实例所属的类,子类实例就调到子类的版本。直接写 Animal.create() 也行,但会把类名写死,子类无法覆盖。

静态方法适合放什么?

和具体实例无关的逻辑,比如工厂方法 User.fromJSON()、工具函数 Array.isArray()、Promise.all(),以及类级别的缓存和配置。

super 在静态方法和实例方法里指向一样吗?

不一样。静态方法里的 super 指向父类本身,也就是 Animal;实例方法里的 super 指向 Animal.prototype。所以静态方法里只能用 super 调父类的静态方法,调不到实例方法。

从一道题,走向一组知识

把知识连起来

对象与原型

怎么用 Symbol.toStringTag 改变 Object.prototype.toString 的输出?

static [Symbol.hasInstance] 这类静态方法能改 instanceof 的结果,和用 Symbol.toStringTag 改类型标签是同一类「内置 Symbol 定制对象行为」的写法。

对象与原型

用 WeakMap 怎么模拟 class 的私有属性?和 # 私有字段比各有什么优劣?

静态私有字段 static #x 不会被子类继承,从子类调用去读会报错。# 私有字段「只认定义它的那个类」的规则,在和 WeakMap 方案对比时还会再遇到。

参考资料

  • JavaScript:对象与原型参考资料

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

本题目录
  1. 先记住这个答案
  2. 一个工厂方法看清继承、super 和 this
  3. 用 ES5 的写法理解它
  4. 容易答错的地方
  5. 面试官还会怎么问
  6. 把知识连起来
读懂,再试着讲出来

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

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