Node.js中如何将类的私有方法绑定到类实例(this)上?
首先得说清楚为什么你原来的BindMethods函数处理不了私有方法——ES6+的私有方法(以#开头的那种)是真正的类私有成员,它们不会出现在类的原型对象上,也无法通过外部的属性遍历方法(比如Object.getOwnPropertyNames)获取到,所以你的工具函数根本“看不到”这些私有方法,自然没法绑定。
针对你的需求,我给你几个实用的解决方案,都是适配Node.js环境的:
方案一:在构造函数里手动绑定私有方法
这是最直接的方式,因为私有方法只能在类内部访问,所以你可以直接在构造函数里把每个私有方法绑定到实例:
class Test { constructor() { UTILS.BindMethods.call(this); // 继续绑定公共方法 // 手动绑定私有方法到当前实例 this.#MyPrivate = this.#MyPrivate.bind(this); } Test() { // 'this' 正常指向实例 } #MyPrivate() { // 现在这里的'this'也指向实例了 } }
如果有多个私有方法,就逐个绑定就行。这样当你把this.#MyPrivate作为引用放进函数数组、或者作为回调传递时,它的this就会固定指向类实例。
方案二:在类内部写个私有绑定方法统一处理
如果私有方法比较多,单独写在构造函数里太乱,可以专门写一个私有方法来统一绑定所有私有方法:
class Test { constructor() { UTILS.BindMethods.call(this); this.#bindAllPrivateMethods(); } Test() { /* ... */ } #MyPrivate() { /* ... */ } #AnotherPrivate() { /* ... */ } #bindAllPrivateMethods() { // 批量绑定私有方法 this.#MyPrivate = this.#MyPrivate.bind(this); this.#AnotherPrivate = this.#AnotherPrivate.bind(this); } }
这种方式更整洁,也符合“类内部的逻辑自己处理”的原则,毕竟私有方法本来就是类的内部成员。
为什么原来的工具函数搞不定私有方法?
再帮你理一遍逻辑:你原来的BindMethods是通过Object.getPrototypeOf(this)拿到类的原型,然后遍历原型上的属性名来找到公共方法。但ES私有方法是存储在类的私有作用域里,不属于原型对象,外部(包括你的工具函数)根本无法访问这些私有成员的名称或引用,所以自然没办法对它们进行绑定操作。
补充注意点
如果你需要把私有方法作为引用传递(比如放进函数数组),一定要确保绑定之后再传递。比如先在构造函数里绑定好this.#MyPrivate,之后再把它放进数组,这样数组里的方法已经是绑定好this的版本了。
备注:内容来源于stack exchange,提问作者yo3hcv

