子类静态方法中调用父类构造函数失效问题:为何无法正常执行?
为什么子类静态方法里的
super(title)无法调用父类构造函数? 这个问题的核心在于静态方法里的super和实例方法里的super完全不是一回事,咱们拆开来说:
1. 实例方法中的super是怎么工作的?
当你在子类的实例方法(包括构造函数)里用super()时,它的作用是在当前实例的上下文中调用父类的构造函数,相当于Todo.call(this, title)。这时候this指向的是正在创建的子类实例,所以父类构造函数里的this.title、this.id都会正确挂载到实例上,_todos.push也能正常执行——这就是为什么你在实例方法(包括constructor)里用super没问题。
2. 静态方法中的super完全是另一个东西
静态方法是直接挂载在类本身(比如TodoV2)上的,这里的super指向的是父类的构造函数对象(也就是Todo这个函数本身),而不是父类的原型,也不是用来创建实例的上下文。
你在TodoV2.addTodo里写super(title),本质上就是直接调用Todo(title)——这是把父类构造函数当成普通函数来调用,不是用new关键字触发构造流程。这时候:
- 严格模式下(类内部默认是严格模式),函数里的
this是undefined,所以this.id = ...会直接抛出错误 - 就算不报错,这种调用方式也不会创建
Todo实例,自然不会触发你预期的构造逻辑(比如把数据推到_todos里)
正确的写法:如果想在静态方法里创建实例
如果你想通过静态方法创建父类或子类的实例,得用new关键字配合super(或者this):
class TodoV2 extends Todo { static addTodo(title) { // 创建父类Todo的实例 return new super(title); // 或者想创建子类TodoV2的实例,用下面的写法: // return new this(title); } // ...其他代码 };
这样调用TodoV2.addTodo("play guitar")时,就会正确触发父类的构造函数,创建对应的实例,同时把数据推到_todos里。
一句话总结
- 实例方法里的
super:绑定当前实例,super(...)是初始化实例的父类构造逻辑 - 静态方法里的
super:指向父类构造函数本身,必须用new super(...)才能创建父类实例
内容的提问来源于stack exchange,提问作者MORA
相关产品推荐
相关产品推荐

