JavaScript类中实现可链式调用的兼具Getter特性的方法
实现方案:无参时省略f3括号并保持链式调用
首先明确:JavaScript不允许在类中同时定义同名的方法和getter——因为两者都会挂载到类的原型对象上,同名情况下后定义的会覆盖先定义的,所以直接同时声明f3()方法和get f3()是行不通的。
要实现你要的效果(传参时带括号调用,无参时直接访问属性并保持链式),可以通过Proxy代理来模拟这种行为,具体实现如下:
修改后的XYZ类代码
class XYZ { constructor() { this.text = null; } f1() { // Do Something return this; } f2() { // Do Something return this; } // 把f3改成getter,返回代理对象 get f3() { const self = this; // 无参时执行的逻辑 const runWithoutArgs = () => { // Do Something return self; }; // 传参时执行的逻辑 const runWithArgs = (txt = null) => { if (txt) { self.text = txt; self.show(); } // Do Something return self; }; return new Proxy(runWithoutArgs, { // 拦截函数调用(obj.f3("Hello")的场景) apply(target, thisArg, args) { return runWithArgs(...args); }, // 拦截属性访问(obj.f3.f2()的场景) get(target, prop) { // 先执行无参逻辑 runWithoutArgs(); // 返回实例对应属性,维持链式调用 return self[prop]; } }); } show() { console.log(this.text); } }
测试调用
const obj = new XYZ(); // 传参时正常调用,保持链式 obj.f1().f2().f3("Hello").f1(); // 无参时省略括号,直接访问f3后继续链式调用f2 obj.f1().f2().f3.f2();
原理说明
- 将
f3改为getter,每次访问obj.f3都会返回一个Proxy对象; - 当用括号调用(
f3("Hello"))时,Proxy的apply拦截器触发,执行带参逻辑并返回实例本身; - 当直接访问
f3后续属性(f3.f2)时,Proxy的get拦截器触发,先执行无参逻辑,再返回实例的对应方法,确保链式调用不中断。
内容的提问来源于stack exchange,提问作者Himanshu Agrawal
相关产品推荐
相关产品推荐

