让我说我有一个正在通过代理处理的正则表达式(为了捕获属性访问等):
proxy = new Proxy(/x/, {});
但是当我尝试使用代理作为正则表达式时:
proxy.test('x')
我得到了
Uncaught TypeError: Method RegExp.prototype.test called on incompatible receiver [object Object]
'x'.match(proxy)
发生了类似的错误。
或者考虑代理一个盒装原语:
proxy = new Proxy(Object(5), {});
但是当我尝试将代理用作表达式的一部分时,期望值为6
:
proxy + 1
我得到了
Uncaught TypeError: Number.prototype.valueOf is not generic(…)
所以我的问题是:
我是否可以代理正则表达式,使代理功能正如regexp在regexp.test
等构造中所做的那样?
我能否以valueOf
行为继续有效的方式代理盒装基元?
答案 0 :(得分: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];
}
});
此示例在每次调用时创建一个新函数。更复杂的解决方案将缓存函数并仅为有问题的方法创建新函数。