【问题标题】:What is a revocable proxy in JavaScript for?JavaScript 中的可撤销代理有什么用?
【发布时间】: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 谢谢你的例子。我已经在我的问题中进一步回复了你。
  • 不清楚你所说的“如果你刚刚删除了代理对象
  • 是的,所以如果这是对它的最后剩余引用,它应该被垃圾回收。

标签: javascript proxy-object


【解决方案1】:

revocable 功能允许目标对于 GC 来说是不可访问的和可被排除的,即使仍然有对其代理的引用。当我们想要“取消”对我们之前提供的底层资源的访问时,这很有用,例如在某些库中。

GC 的默认行为仍然有效,即删除对代理及其目标的引用也将允许它可用于 GC。

【讨论】:

  • 我认为第二个代码 sn-p 解决了垃圾收集问题。通过创建一个允许我“'取消'对底层资源的访问”的瘦包装器,我相信目标有资格获得 GC。那么,Proxy.revokable() 只是一种方便的方法,还是它对我的第二版 createRevocable() 之外的语言做了更多的事情?
  • 该机制是在 js 引擎中实现的,该引擎的运行级别低于您的示例可以访问的级别,也许阅读 source 将为您提供一些答案。
  • 好点。谢谢你。我去看看。
猜你喜欢
  • 1970-01-01
  • 2011-04-09
  • 2015-09-02
  • 2014-06-14
  • 1970-01-01
  • 2021-07-29
  • 2011-05-19
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多