Ecmascript 6 regexp和装箱原语上的代理

Ecmascript 6 regexp和装箱原语上的代理,ecmascript-6,Ecmascript 6,假设我有一个regexp,我想通过代理处理它(以便捕获属性访问等): 但当我尝试将代理用作regexp时: proxy.test('x') 我明白了 未捕获类型错误:在不兼容的接收器[对象]上调用了方法RegExp.prototype.test 类似的错误发生在'x'。匹配(代理) 或考虑代理装箱原语: proxy = new Proxy(Object(5), {}); 但当我尝试将代理用作表达式的一部分时,期望值为6: proxy + 1 我明白了 未捕获类型错误:Number.prot

假设我有一个regexp,我想通过代理处理它(以便捕获属性访问等):

但当我尝试将代理用作regexp时:

proxy.test('x')
我明白了

未捕获类型错误:在不兼容的接收器[对象]上调用了方法RegExp.prototype.test

类似的错误发生在
'x'。匹配(代理)

或考虑代理装箱原语:

proxy = new Proxy(Object(5), {});
但当我尝试将代理用作表达式的一部分时,期望值为
6

proxy + 1
我明白了

未捕获类型错误:Number.prototype.valueOf不是泛型(…)

因此,我的问题是:

  • 我是否可以代理一个regexp,使代理的功能与regexp在诸如
    regexp.test
    之类的构造中的功能相同

  • 我是否可以以
    valueOf
    行为继续工作的方式代理已装箱的原语


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

    当代理对象时,无法通过标准方式访问这些内部插槽。查看规范时,您经常会遇到“如果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];
     }
    });
    
    此示例在每次调用时创建一个新函数。更复杂的解决方案将缓存函数,并仅为有问题的方法创建新函数

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