【问题标题】:Illegal invocation while intercepting method calls with javascript proxy使用 javascript 代理拦截方法调用时非法调用
【发布时间】:2018-08-21 22:11:54
【问题描述】:

谁能解释一下下面的输出

var handler = {
  get: function(target,key, receiver){
    return new Proxy(Reflect.get(target, key, receiver),handler);
  }, 
  apply: function(target, thisArg, args){
    Reflect.apply(target, thisArg, args);
  }
}

var p = new Proxy(window, handler);
p.alert("Alert"); // Throws illegal invocation error

var alias = p.alert;
alias("Alert") // Even this works which is baffling for me

var p = new Proxy(Reflect.get(window, "alert"), handler);
p("Alert"); // works as expected

第一条语句抛出非法调用错误,而第二条则没有。他们两个看起来和我一模一样,我不明白第一个语句在Reflect.apply 期间没有所需的this 上下文

【问题讨论】:

  • 对于@ibrahimmahrir 的答案,因为它适用于您的代理,请参阅alert.call(new Proxy(window, {}), "alert") 产生的错误
  • 在没有明确上下文的情况下调用函数时,上下文将为window。显式上下文:在obj.funcfunc.call(obj) 中,上下文将为obj
  • @Ry- 感谢这个精彩的例子,它实际上回答了这个问题。所以将目标的代理对象作为上下文传递与将目标本身作为上下文传递是不一样的,这实际上是有道理的。

标签: javascript javascript-objects es6-proxy


【解决方案1】:

只是alert 需要window 作为上下文,否则会抛出该错误。它与代理无关。这两个例子抛出了同样的错误:

var obj = {};
alert.call(obj, "hello!");           // doesn't work!

和:

var obj = { alert: alert };
obj.alert("hello!");                 // doesn't work!

在您的代码中,如果您将p.alert 的上下文设置为window,它会起作用:

p.alert.call(window, "hello!");      // works!

var handler = {
  get: function(target, key, receiver) {
    return new Proxy(Reflect.get(target, key, receiver), handler);
  },
  apply: function(target, thisArg, args) {
    Reflect.apply(target, thisArg, args);
  }
}

var p = new Proxy(window, handler);
p.alert.call(window, "Alert");

您的代码中的其他两个示例有效,因为上下文是 window

【讨论】:

  • 谢谢,我将其标记为答案,但这里的代理变得相关的原因是,如果我在 get 处理程序本身内部调用 Reflect.apply,则不再出现此问题,因为现在我调用捕获目标上下文的方法。
猜你喜欢
  • 1970-01-01
  • 2014-10-11
  • 2021-09-16
  • 1970-01-01
  • 1970-01-01
  • 2012-04-01
  • 2012-08-18
  • 2011-10-21
相关资源
最近更新 更多