JavaScriptSet https://developer.mozilla.org/en/docs/Web/JavaScript/Reference/Global_Objects/Set似乎与 JavaScript 完全不兼容proxies https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy,试图Proxy()
a 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({}, {})
vs p = new Proxy(new Set(), {})
。 (这适用于 Firefox (52.0.2) 和 Chromium (57.0.2987.133)。)
我似乎找不到可靠的参考或文档,为什么 JavaScript 不能Proxy
a Set
对象以及为什么它会遇到虚拟机错误?
我正在尝试Proxy()
a Set()
但是,您还没有使用过任何可用的陷阱 https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Global_Objects/Proxy/handler- 没有add
一。您可以在通话中拦截的所有内容p.add(55)
is the 财产访问权 to .add
在代理上,它通过get
陷阱并返回一个函数。
如果您想拦截对add
方法,您根本不需要代理,更好(子类化和)覆盖该方法,类似于.set
被覆盖here https://stackoverflow.com/a/42381180/1048572 and here https://stackoverflow.com/a/43236808/1048572 for 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`
Calling Set
非 True Sets 对象上的方法确实会抛出异常(例如可用于检测它们 https://stackoverflow.com/a/29926193/1048572)。对于您的具体情况,请参阅ECMAScript 6 §23.2.3.1 http://www.ecma-international.org/ecma-262/6.0/#sec-set.prototype.add:
"If S
没有[[SetData]]
内部插槽,扔一个TypeError
例外。"
确实,p
是一个代理(它确实有内部代理方法和槽 http://www.ecma-international.org/ecma-262/6.0/#sec-proxy-object-internal-methods-and-internal-slots, 尤其[[ProxyHandler]]
and [[ProxyTarget]]
)而不是像这样的集合s
以其[[SetData]]
内部插槽。
你合理地期望“如果尚未定义陷阱,则默认行为是将操作转发到目标”,但是这只适用于属性访问等标准行为,而不适用于外来对象的内部插槽。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)