JavaScript Set似乎与JavaScript proxies完全不兼容,尝试Proxy()
Set()
var p = new Proxy(new Set(), {
add(target, val, receiver) {
console.log('in add: ', target, val, receiver)
}
})
p.add(55)
导致VMError:
Uncaught TypeError: Method Set.prototype.add called on incompatible receiver [object Object]
at Proxy.add (native)
at <anonymous>:1:3
事实上,代理Set()
以任何方式断断续续 - 即使我们的代理处理程序什么都不做!比较p = new Proxy({}, {})
与p = new Proxy(new Set(), {})
。 (这适用于Firefox(52.0.2)和Chromium(57.0.2987.133)。)
我似乎无法为此找到可信的参考或文档,为什么JavaScript Proxy
不能成为Set
对象,为什么它会遇到VM错误?
答案 0 :(得分:6)
我正在尝试
Proxy()
Set()
但是,您还没有使用available traps中的任何一个 - 没有add
个。您可以在调用p.add(55)
中拦截的所有内容是代理上的属性访问到.add
,它通过get
陷阱并返回一个函数。< / p>
如果您想拦截对add
方法的调用,您根本不需要代理,更好(子类和)覆盖该方法类似于覆盖.set
的方式{{ 3}}和here Map
。
代理
Set()
以任何方式断断续续地
是的,因为代理不再是Set
。
var s = new Set([42]);
var p = new Proxy(s, {});
s.has(42) // true
console.log(s === p) // false
p.has.call(s, 42) // true
p.has(42) // exception - calls `has` on `p`, not on `s`
在没有True Sets的对象上调用Set
方法会抛出异常(例如here)。对于您的具体情况,请参阅can be used for detecting them:
&#34; 如果
S
没有[[SetData]]
内部广告位,请抛出TypeError
例外。&#34;
事实上,p
是一个代理(确实有ECMAScript 6 §23.2.3.1,特别是[[ProxyHandler]]
和[[ProxyTarget]]
),而不是像s
这样的集合[[SetData]]
内部广告位。
你有理由期待&#34; 如果没有定义陷阱,默认行为是将操作转发到目标&#34;但是这只适用于标准行为喜欢属性访问,而不是异国情调对象的内部插槽。