如何在JavaScript中定义async static protected类成员?
原生JavaScript(ES6及之后的标准)没有内置protected访问修饰符的语法支持,你写的带protected关键字的代码仅能在TypeScript等JS超集环境下运行。如果要在原生JS中实现仅允许类自身、子类访问的protected静态async方法,可以按以下两种场景实现:
ES6 class语法实现
约定式实现(工程通用方案)
业界通用的软实现方案,用下划线前缀标记受保护成员,只要团队遵守约定不直接对外调用即可,语法完全合法:
module.exports = class MyClass { // 下划线开头为约定的protected标记,仅允许本类、子类调用,禁止外部直接调用 static async _foo(bar) { // 方法逻辑 return bar * 2 } // 类内部调用示例 static async testInvoke() { return this._foo(123) } } // 子类调用示例 class ChildClass extends MyClass { static async childInvoke() { return this._foo(456) } }
强限制实现(外部完全无法访问)
如果需要硬限制外部访问权限,可以借助闭包+WeakMap实现:
// 闭包内的WeakMap外部无法访问,用来存储受保护方法 const protectedStaticMethods = new WeakMap() module.exports = class MyClass { static { // 静态块注册当前类的受保护方法 protectedStaticMethods.set(this, { foo: async (bar) => { return bar * 2 } }) } // 类内部调用示例 static async testInvoke() { return protectedStaticMethods.get(this).foo(123) } } // 子类调用示例 class ChildClass extends MyClass { static { // 子类继承父类的受保护方法 protectedStaticMethods.set(this, { ...protectedStaticMethods.get(MyClass) }) } static async childInvoke() { return protectedStaticMethods.get(this).foo(456) } }
普通JS(构造函数原型)实现
约定式实现
// 构造函数定义 function MyClass() {} // 下划线标记protected静态async方法 MyClass._foo = async function(bar) { return bar * 2 } // 内部调用示例 MyClass.testInvoke = async function() { return this._foo(123) } // 子类继承 function ChildClass() {} Object.setPrototypeOf(ChildClass, MyClass) // 子类调用示例 ChildClass.childInvoke = async function() { return this._foo(456) } module.exports = MyClass
强限制实现
// 闭包隐藏WeakMap实例 (function() { const protectedStaticMethods = new WeakMap() function MyClass() {} // 注册受保护方法 protectedStaticMethods.set(MyClass, { foo: async (bar) => { return bar * 2 } }) MyClass.testInvoke = async function() { return protectedStaticMethods.get(this).foo(123) } // 子类实现 function ChildClass() {} Object.setPrototypeOf(ChildClass, MyClass) protectedStaticMethods.set(ChildClass, { ...protectedStaticMethods.get(MyClass) }) ChildClass.childInvoke = async function() { return protectedStaticMethods.get(this).foo(456) } module.exports = MyClass })()
如果是在TypeScript环境下,你写的前两种顺序protected static async、static protected async都是合法可运行的,仅第三种顺序不支持。
内容的提问来源于stack exchange,提问作者Web Jigooli
相关产品推荐
相关产品推荐

