簡體   English   中英

在 Node.js 上使用 Proxy.apply() 不起作用。 這是一個錯誤還是我做錯了?

[英]Using Proxy.apply() on Node.js does not work. Is this a bug or am I doing it wrong?

我正在使用代理來代理一個對象。 getter 和 setter 可以正常工作。 但是,從不調用 apply 方法。

    var p = new Proxy({}, {
    /* getter */
    get(target, name) {
        return target[name]
    },
    /* setter */
    set(target, name, value) {
        target[name] = value
    }, 
    /* supposedly called apply */
    apply(target,that,arg) {
        console.log('apply is called, what to do here?')        
    }
})

這樣,即使它不存在,我也可以將某些內容分配給p或返回某些內容。 例如,當我讓 getter 函數返回這個時

get(target, name) {
    return 'getting ' + name
},

然后console.log(p.flappy)我會得到響應“getting flappy”,即使它不存在。

到目前為止一切p.flapppy()但是當我嘗試調用 flappy 做p.flapppy()它會拋出一個錯誤,即 flappy 不是函數。

這仍然有些明顯,因為 getter 不返回函數。 當我讓 getter 返回這樣的函數時

get(target, name) {
    return function() { return 'this is '+name } 
},

我可以調用該屬性而無需它存在。

console.log(
    p.flappy() // this is flappy!
)

那么什么時候申請會被調用? 不在我剛剛在這里展示的片段中,也不是在這種情況下:

p.foo = function() {
    console.log('yay!')
    return 'foo!'
}

它不起作用p.foo()p.foo.call()p.foo.apply() ,在這兩種情況下都調用 apply 。

這個旅程的最終目的是我想根據屬性是被讀取還是被調用來返回一個不同的值。 像這樣:

   p.someNewProperty // return what the getter function returns

    p.anotherProperty() // return something else here because this is a function call

這可能嗎?

我知道這是一個問題,但我也遇到了這個問題,我找到了一種方法來做你想做的事情。 所以這是為了將來參考,因為我沒有在其他地方找到正確的解決方案。

簡短版本:訪問對象(或類)內的函數本質上是get具有該函數的對象的屬性。 訣竅是使用apply返回另一個代理,以便您可以正確代理這些功能。

考慮以下對象:

const myObject = {
  a: 'Hello world!',
  b: x => x * x
};

訪問ab都將被代理的get捕獲,因為它們是對象的屬性。 您應該捕獲所有get然后過濾函數。 一旦你有了一個函數,你就會返回一個新的代理,它用Proxy.apply捕獲這個特定的函數。 然后,為了讓函數按預期執行,在Proxy.apply我們返回一個Reflect.apply ,它按預期使用正確的參數調用原始函數。

你最終會得到這個代碼:

const myProxyObject = new Proxy(myObject, {
  get(target, propKey, receiver) {    
    // Calling functions
    if (typeof target[propKey] === 'function') {
      return new Proxy(target[propKey], {
        apply(applyTarget, thisArg, args) {
          console.log(`Calling ${thisArg.constructor.name}.${propKey}(${args})`);
          return Reflect.apply(applyTarget, thisArg, args);
        }
      });
    }

    // Accessing properties
    if (target.hasOwnProperty(propKey)) {
      console.log(`Get value of ${target.constructor.name}.${propKey}`);
      console.log(`Value: ${target[propKey]}`);
    }

    return target[propKey];
  }
});

jsfiddle 上的演示

您不會得到函數的結果,因為那需要您執行它。

注意:可以將它與一起使用,並且效果很好。 唯一需要注意的是,您的代理也將捕獲所有內部功能。 為了防止記錄數十個valueOf ,我強烈建議使用類似 isNative 函數來測試一個函數是否是原生的

MDN 上所述, apply代理方法用於代理對代理對象本身的函數調用,而不是對對象方法的調用。

它僅適用於函數(作為代理目標) ,而不適用於常規對象實例,但它的工作方式如下:

var p = new Proxy(function() {}, {
    apply: function() {
        console.log('apply called');
    }
});
p();

這個旅程的最終目的是我想根據屬性是被讀取還是被調用來返回一個不同的值。

直接做你想做的事情是不可能的,也沒有真正的意義。 調用就是讀取屬性。

幾年后……

是的,你可以! 您可以根據屬性是被讀取還是被調用來返回不同的值!

 const authUser = { id: 1 } const user = new Proxy(function () {}, { get (target, property) { return authUser.id }, apply (target, thisArg, args) { // some stuff to get user return { id: args[0] } } }) console.log(user.id) console.log(user(2).id)

或者您可以使用兩步代理。

 const authUser = { id: 1 } const user = new Proxy(function () {}, { get (target, property) { return userProxy(authUser.id, property) }, apply (target, thisArg, args) { return userProxy(args[0]) } }) function userProxy(id, property) { // some stuff to get user const user = { id } return property ? user[property] : new Proxy(user, { get (target, property) { return user[property] } }) } console.log(user.id) console.log(user(2).id)

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM