Node.js中使用Proxy模擬PHP的__callStatic屬性的方法
P粉653045807
P粉653045807 2023-09-04 09:05:21
0
1
478
<p>我正在嘗試在Node.js中創建與PHP <code>__callStatic</code> 魔術方法相同的行為。 </p> <p>我正在嘗試使用<code>Proxy</code>來實現,但我不確定是否是最佳選擇。 </p> <p> <pre class="snippet-code-js lang-js prettyprint-override"><code>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</code></pre> </p> <p>問題在於每次我嘗試訪問<code>TestFacade</code>的屬性時,<code>get</code>陷阱都會被觸發。我需要的行為是,當呼叫<code>set</code>方法時,它將返回<code>Test</code>類別的<code>this</code>,我甚至可以保存該實例以後使用! </p> <pre class="brush:php;toolbar:false;">const testInstance = TestFacade.set(10) // set方法回傳`Test`的`this`而不是Proxy</pre> <p>如果有什麼不清楚的地方,請告訴我。 </p>
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
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板
關於我們 免責聲明 Sitemap
PHP中文網:公益線上PHP培訓,幫助PHP學習者快速成長!