JavaScript基类如何访问类继承链上所有层级的静态属性?
实现结论
完全可以实现,核心思路是遍历实例对应构造函数的原型链,逐层收集所有父类的静态NUMBERS属性后合并即可。
核心实现代码
只需要修改基类Tier1的getNumbers方法:
class Tier1 { static NUMBERS = ['one', 'two']; getNumbers() { let currentClass = this.constructor; const allNumbers = []; // 遍历构造函数的原型链,直到顶端null while (currentClass) { // 仅收集当前类自身定义的NUMBERS静态属性 if (Object.hasOwn(currentClass, 'NUMBERS')) { // 插入数组头部,保证父类属性在前、子类属性在后 allNumbers.unshift(...currentClass.NUMBERS); } // 向上获取父类构造函数 currentClass = Object.getPrototypeOf(currentClass); } return allNumbers.join(', '); } } // 其余子类代码无需修改 class Tier2 extends Tier1 { static NUMBERS = ['three']; } class Tier3 extends Tier2 { static NUMBERS = ['four', 'five']; } class Tier4 extends Tier3 { static NUMBERS = ['six']; }
效果验证
调用后完全符合预期输出:
const t1 = new Tier1(); console.log(t1.getNumbers()); // 输出 "one, two" const t2 = new Tier2(); console.log(t2.getNumbers()); // 输出 "one, two, three" const t3 = new Tier3(); console.log(t3.getNumbers()); // 输出 "one, two, three, four, five" const t4 = new Tier4(); console.log(t4.getNumbers()); // 输出 "one, two, three, four, five, six"
实现原理
- JavaScript的类继承中,子类构造函数的内部
[[Prototype]]属性会指向父类构造函数,因此可以通过Object.getPrototypeOf逐层向上获取整条继承链上的所有构造函数 - 使用
Object.hasOwn判断是为了过滤掉继承来的同名属性,确保只收集每个类自身定义的NUMBERS - 收集时用
unshift插入数组头部,自动保证了父类属性在前、子类属性在后的顺序,无需额外排序
性能优化方案
如果静态属性不会动态修改,可以新增静态缓存字段避免重复遍历:
getNumbers() { const currentClass = this.constructor; // 已缓存过直接返回结果 if (Object.hasOwn(currentClass, '_cachedNumbers')) { return currentClass._cachedNumbers.join(', '); } let cls = currentClass; const allNumbers = []; while (cls) { if (Object.hasOwn(cls, 'NUMBERS')) { allNumbers.unshift(...cls.NUMBERS); } cls = Object.getPrototypeOf(cls); } // 缓存结果,后续调用无需重新遍历 currentClass._cachedNumbers = allNumbers; return allNumbers.join(', '); }
内容的提问来源于stack exchange,提问作者mraxus
相关产品推荐
相关产品推荐

