【发布时间】:2017-02-28 19:49:11
【问题描述】:
我想了解为什么无法使用 ES6 创建“通用”转发代理。 “通用”是指代理目标可以是具有相同代理声明(构造函数 + 处理程序)的任何类型的非原始值(包括函数)。
案例一:
var o = function myCtor() {}
var p = new Proxy({}, {
construct: function(target, ...args) {
return Reflect.construct(o, ...args);
}
});
console.log(new p); // TypeError: p2 is not a constructor
案例2:
var o = {}
var p = new Proxy(function() {}, {
ownKeys: function(target) {
return Reflect.ownKeys(o);
}
});
console.log(Object.keys(p)); // TypeError: 'ownKeys' on proxy: trap result did not include 'arguments'
当我使用 function(){} 作为代理目标(而不是 {})时,案例 1 可以正常工作,但是之后,案例 2 不再有效。
感谢您的帮助。
【问题讨论】:
-
函数具有以下属性:
length、name、arguments,caller` 和prototype。似乎包装函数的代理期望arguments在键列表中。可能还有其他人,但解决这个问题就像return ['arguments', ...Reflect.ownKeys(o)]一样简单。 -
@FelixKling 骗子! :)
-
见developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/…:“结果列表必须包含目标对象所有不可配置的自身属性的键。”
-
您观察到的行为是代理在 ECMAScript 中保留 Invariants of the Essential Internal Methods 的结果。
-
@FelixKling 你能解释为什么“结果列表必须包含目标对象的所有不可配置的自身属性的键。”吗?我想使用代理通过使用数组索引映射到代理处理程序中的字段名称来使数组(目标)看起来是一个对象。我当然没有理由让 ownKeys 方法将长度作为属性返回,为什么 ECMA 脚本有这个要求?我希望 ownKeys() 简单地从字段/索引映射中返回字段名称列表(不必包含“长度” - 除非这是其中一个字段的名称)。
标签: javascript ecmascript-6 es6-proxy