【发布时间】:2020-02-12 19:38:02
【问题描述】:
您为什么要撤销代理?能否提供一个Proxy.revocable()的实际应用?
基于MDN Proxy.revocable() documentation 我理解它允许垃圾收集。但是,如果您只是删除了 Proxy 对象,它是否也允许垃圾收集?
附录:如果这个问题有什么问题,请告诉我是什么问题,我很乐意重新措辞或添加更多信息。
@艾米:
我认为这似乎是一个不必要的内置功能,因为我可以像这样创建一个可撤销的代理:
function createRevocable(o,handlers){
var revoked = false
var handlerWrapper = {
get(...args){
if(revoked){
throw Error('Sorry, this object went poof.')
}
if(typeof handlers.get == 'function'){
return handlers.get(...args)
}else{
return Reflect.get(...args)
}
}
}
var p = new Proxy(o,Object.assign({},handlers,handlerWrapper))
var r = function(){
revoked = true
}
return {r,p}
}
var a = createRevocable({a:1},{})
var prox = a.p
var revoke = a.r
console.log(prox.a) //1
revoke()
console.log(prox.a)
但是,垃圾回收似乎确实是个问题,因为我可以撤消对象的访问权限,但不能删除 Proxy 对象内部对它的内部引用。除非……
function createRevocable(o,handlers){
var revoked = false
var proxyProxyHandlers = {
get(target,prop,rec){
if(revoked){
throw Error('Sorry, this object went poof.')
}
return p[prop]
}
,//etc...
}
var p = new Proxy(o,handlers)
var proxyProxy = new Proxy(Object.create(null),proxyProxyHandlers)
var r = function(){
// Delete the one and only reference to the proxy:
delete p
revoked = true
}
return {r,p:proxyProxy}
}
var a = createRevocable({a:1},{})
var prox = a.p
var revoke = a.r
console.log(prox.a) //1
revoke()
console.log(prox.a)
因此,通过创建一个两层代理,您可以创建一个可回收和可撤销的垃圾代理。那么,为什么要内置呢?使用方便?还是我错过了什么?虽然它不是完全垃圾可回收的,但仍然有一个瘦包装器,其中包含对具有空原型的对象的引用。
【问题讨论】:
-
假设您在整个系统中都有这些代理。你想删除一个,但你不能确定你已经从系统的任何地方删除了它。撤销它使得代理在使用时会抛出错误;让您追踪并删除该使用情况。
-
或者你有一个第三方库来发布这些代理。它无法控制这些代理将如何在图书馆外使用,但是当它想确定图书馆的用户不能继续使用过期的代理时,它可以撤销它,除了询问其他系统无能为力另一个代理。
-
@Amy 谢谢你的例子。我已经在我的问题中进一步回复了你。
-
不清楚你所说的“如果你刚刚删除了代理对象”
-
是的,所以如果这是对它的最后剩余引用,它应该被垃圾回收。