Estoy tratando de crear el mismo comportamiento del método mágico PHP __callStatic en Node.js.
Estoy tratando de usar Proxy para hacer eso, pero realmente no sé si es la mejor opción.
class Test { constructor() { this.num = 0 } set(num) { this.num = this.num + num return this } get() { return this.num } } const TestFacade = new Proxy({}, { get: (_, key) => { const test = new Test() return test[key] } }) // Execution method chain ends in get console.log(TestFacade.set(10).set(20).get()) // expected: 30 // returns: 0 // Start a new execution method chain and should instantiate Test class again in the first set console.log(TestFacade.set(20).set(20).get()) // expected: 40 // returns: 0 El problema es que la trampa get se activa cada vez que intento acceder a una propiedad de TestFacade . El comportamiento que necesito es que cuando se llame al método set , devolverá this de la clase Test e incluso puedo guardar la instancia para un uso posterior.
const testInstance = TestFacade.set(10) // set method return this of `Test` not the ProxySi algo no está claro, por favor hágamelo saber.
No sé si es la mejor opción. Pero lo resolví, devolviendo un nuevo Proxy dentro de get trampa que usa la trampa de apply para vincular la instancia de clase de test en el método:
class Facade { static #facadeAccessor static createFacadeFor(provider) { this.#facadeAccessor = provider return new Proxy(this, { get: this.__callStatic.bind(this) }) } static __callStatic(facade, key) { /** * Access methods from the Facade class instead of * the provider. */ if (facade[key]) { return facade[key] } const provider = new this.#facadeAccessor() const apply = (method, _this, args) => method.bind(provider)(...args) if (provider[key] === undefined) { return undefined } /** * Access the properties of the class. */ if (typeof provider[key] !== 'function') { return provider[key] } return new Proxy(provider[key], { apply }) } } class Test { num = 0 set(num) { this.num = this.num + num return this } get() { return this.num } } const TestFacade = Facade.createFacadeFor(Test) console.log(TestFacade.set(10).set(20).get()) // 30 console.log(TestFacade.set(5).set(5).get()) // 10 const testInstance = TestFacade.set(10) console.log(testInstance.num) // 10 console.log(testInstance.get()) // 10 console.log(testInstance.set(10).get()) // 20