关于正则表达式和盒装基元的代理

6 ecmascript-6

假设我有一个我想通过代理处理的正则表达式(为了捕获属性访问等):

proxy = new Proxy(/x/, {});
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用代理作为正则表达式时:

proxy.test('x')
Run Code Online (Sandbox Code Playgroud)

我明白了

Uncaught TypeError: Method RegExp.prototype.test called on incompatible receiver [object Object]

发生类似的错误'x'.match(proxy).

或者考虑代理一个盒装原语:

proxy = new Proxy(Object(5), {});
Run Code Online (Sandbox Code Playgroud)

但是当我尝试使用代理作为表达式的一部分时,期望值为6:

proxy + 1
Run Code Online (Sandbox Code Playgroud)

我明白了

Uncaught TypeError: Number.prototype.valueOf is not generic(…)

所以我的问题是:

  1. 我可以代理一个正则表达式,使代理功能正如regexp在构造中所做的那样regexp.test吗?

  2. 我可以以一种valueOf行为继续工作的方式代理盒装基元吗?

a b*_*ver 4

内置类型/对象可以具有所谓的“内部槽”,其携带无法从外部访问的状态。某些方法依赖于此状态,因此如果缺少该状态则无法运行。

当对象被代理时,这些内部槽无法通过标准方式访问。查看规范时,您经常会遇到“如果 X 没有 [[y]] 内部槽,则抛出 TypeError 异常”。这就是代理内置类型通常无法按预期工作的原因。出于同样的原因,你不能做类似的事情 Number.prototype.valueOf.call({})

解决方法是将函数直接绑定到代理的目标:

var proxy = new Proxy(/x/, {
  get: function(target, key) {
    if (typeof target[key] === 'function') {
      return target[key].bind(target);  
    }

    return target[key];
 }
});
Run Code Online (Sandbox Code Playgroud)

此示例在每次调用时都会创建一个新函数。更复杂的解决方案将缓存函数,并仅为有问题的方法创建新函数。