JavaScript:子类未定义静态方法时,如何正确调用父类静态方法?
解决JavaScript静态方法无法跨子类递归调用父类方法的问题
问题原因
你当前的代码中,SubControl和AnotherControl都没有重写GetCodeChain静态方法,调用AnotherControl.GetCodeChain()时实际执行的是Control类中的方法。此时方法里的super.GetCodeChain指向的是Control的父类(原生Function构造函数)的方法,显然不存在,因此只会收集当前类的Code值,导致输出不符合预期。
解决方案
由于不能在子类中编写静态方法,我们需要修改Control类的GetCodeChain实现,通过遍历类的构造函数原型链来递归收集所有父类的Code值,替代依赖super的调用方式。
方案1:循环遍历原型链
class Control { static Code = 3; static GetCodeChain() { const result = [this.Code]; let parentClass = this.__proto__; // 沿着原型链向上遍历,收集所有存在Code的父类属性值 while (parentClass && 'Code' in parentClass) { result.push(parentClass.Code); parentClass = parentClass.__proto__; } return result; } } class SubControl extends Control { static Code = 2; } class AnotherControl extends SubControl { static Code = 1; } console.log(AnotherControl.GetCodeChain()); // 输出 [1, 2, 3]
方案2:递归调用父类方法
class Control { static Code = 3; static GetCodeChain() { const result = [this.Code]; // 通过构造函数的__proto__获取父类,调用其GetCodeChain方法 if (this.__proto__.GetCodeChain) { result.push(...this.__proto__.GetCodeChain()); } return result; } } class SubControl extends Control { static Code = 2; } class AnotherControl extends SubControl { static Code = 1; } console.log(AnotherControl.GetCodeChain()); // 输出 [1, 2, 3]
原理说明
- JavaScript中,类的静态方法和属性挂载在构造函数本身,子类构造函数的
__proto__指向父类构造函数,因此可以通过this.__proto__获取父类。 - 原来的
super调用仅在子类重写静态方法时有效:此时子类方法中的super指向父类构造函数,才能正确调用父类的GetCodeChain。但由于你无法在子类编写静态方法,super的方式无法触发父类方法的递归调用。
内容的提问来源于stack exchange,提问作者Wolfgang Amadeus
相关产品推荐
相关产品推荐

