Can't set 'trap发送到代理对象

Can't set "apply" trap to Proxy object

本文关键字:代理 对象 set Can trap      更新时间:2023-09-26

我创建了一个带有"apply"陷阱:

var target = {},
    handler = { apply: () => 42 }
    proxy = new Proxy(target, handler);
proxy(); // TypeError: proxy is not a function

因此,Proxy对象应该是可调用的。然而,它不工作。

为什么?

根据代理对象的[[Call]]内部方法的定义,它应该工作:

  • trap为GetMethod(handler"apply")。
  • Return Call(traphandler,«targetthisArgument, CreateArrayFromList(argumentsList)»)

然而,有一个问题:不是所有的代理对象都有[[Call]]方法:

一个代理外部对象只有在[[Call]]内部方法其内部槽位[[ProxyTarget]]的初始值为1[[Call]]的内部方法。

因此,目标必须是一个函数对象:

var target = () => {},
    handler = { apply: () => 42 }
    proxy = new Proxy(target, handler);
proxy(); // 42

注意,我使用箭头函数定义target是为了创建一个不是构造函数的函数对象。这样可以调用Proxy对象,但不能实例化。

如果你也想添加一个"construct"陷阱,目标必须有一个[[construct]]方法,所以用函数声明或函数表达式来定义它。

我从Google搜索'callable proxy'来到这里。
虽然现有的答案有效,但对于某些目的,还有另一种选择可能"更干净":

class Callable extends Function {
  constructor() {
    super()    
    return new Proxy(this, {
      apply: (target, thisArg, args) => target._call(...args)
    })
  }
  
  _call(...args) {
    console.log(this, args)
  }
}

您可以像往常一样在代理中定义所有陷阱。
所有的功劳都归功于arccoza和他的主旨。