Cara menggunakan Proksi untuk mensimulasikan atribut __callStatic PHP dalam Node.js
P粉653045807
P粉653045807 2023-09-04 09:05:21
0
1
533
<p>Saya cuba mencipta gelagat yang sama dalam Node.js seperti kaedah ajaib PHP <code>__callStatic</code> </p> <p>Saya cuba melakukannya menggunakan <kod>Proksi</kod> tetapi saya tidak pasti sama ada itu pilihan terbaik. </p> <p> <pre class="snippet-code-js lang-js prettyprint-override"><code>Ujian kelas { pembina() { this.num = 0 } set(bilangan) { this.num = ini.num + num pulangkan ini } dapatkan() { pulangkan this.num } } const TestFacade = Proksi baharu({}, { dapatkan: (_, kunci) => ujian const = Ujian baru () ujian pulangan[kunci] } }) //Rantai kaedah pelaksanaan berakhir dengan get console.log(TestFacade.set(10).set(20).get()) //Hasil yang dijangkakan: 30 // Pulangan keputusan: 0 // Mulakan rantai kaedah pelaksanaan baharu dan nyatakan kelas Ujian sekali lagi dalam set pertama console.log(TestFacade.set(20).set(20).get()) //Hasil yang dijangkakan: 40 // Kembalikan hasil: 0</code></pre> </p> <p>Masalahnya ialah setiap kali saya cuba mengakses sifat <code>TestFacade</code>, perangkap <code>get</code> Tingkah laku yang saya perlukan ialah apabila kaedah <kod>set</kod> ia akan mengembalikan <kod>ini</kod>Ujian</kod> contoh untuk kegunaan kemudian! </p> <pre class="brush:php;toolbar:false;">const testInstance = TestFacade.set(10) // Kaedah set mengembalikan `this` `Test` dan bukannya Proxy</pre> <p>Jika ada yang kurang jelas, sila beritahu saya. </p>
P粉653045807
P粉653045807

membalas semua(1)
P粉549986089

Saya tidak tahu sama ada ini adalah pilihan terbaik. Tetapi saya mengikat kaedah melalui contoh kelas 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
Muat turun terkini
Lagi>
kesan web
Kod sumber laman web
Bahan laman web
Templat hujung hadapan