Node.js中使用Proxy模拟PHP的__callStatic属性的方法
P粉653045807
P粉653045807 2023-09-04 09:05:21
[PHP讨论组]

我正在尝试在Node.js中创建与PHP __callStatic 魔术方法相同的行为。

我正在尝试使用Proxy来实现,但我不确定是否是最佳选择。

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]
  }
})


// 执行方法链以get结束
console.log(TestFacade.set(10).set(20).get())
// 期望结果: 30
// 返回结果: 0

// 开始一个新的执行方法链,并在第一个set中再次实例化Test类
console.log(TestFacade.set(20).set(20).get())
// 期望结果: 40
// 返回结果: 0

问题在于每次我尝试访问TestFacade的属性时,get陷阱都会被触发。我需要的行为是,当调用set方法时,它将返回Test类的this,我甚至可以保存该实例以供以后使用!

const testInstance = TestFacade.set(10) // set方法返回`Test`的`this`而不是Proxy

如果有什么不清楚的地方,请告诉我。

P粉653045807
P粉653045807

全部回复(1)
P粉549986089

我不知道这是否是最佳选择。但是我通过在get陷阱中返回一个新的代理来解决了这个问题,该代理使用apply陷阱将test类实例绑定到方法中:

class Facade {
  static #facadeAccessor

  static createFacadeFor(provider) {
    this.#facadeAccessor = provider

    return new Proxy(this, { get: this.__callStatic.bind(this) })
  }

  static __callStatic(facade, key) {
    /**
     * 访问Facade类的方法而不是提供者的方法。
     */
    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
    }

    /**
     * 访问类的属性。
     */
    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
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送
PHP中文网APP
随时随地碎片化学习

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号