是否有可能在JavaScript中创build一个“弱引用”?
有什么办法在JavaScript中创build一个“弱引用”到另一个对象? 这里是维基页面描述什么是弱引用。 这是另一篇文章,用Java描述它们。 任何人都可以想到一种方法来在JavaScript中实现这种行为?
JavaScript中没有对弱返回的语言支持。 您可以使用手动引用计数来滚动自己,但不是特别顺利。 你不能创build代理包装器对象,因为在JavaScript中,对象永远不知道什么时候被垃圾收集。
所以你的“弱引用”在一个简单的查找中成为一个关键(例如整数),带有一个add-reference和remove-reference方法,并且当没有手动跟踪的引用时,就可以删除条目,留下将来的查询该键返回null。
这不是一个真正的弱点,但它可以解决一些相同的问题。 它通常在复杂的Web应用程序中完成,以防止在DOM节点或事件处理程序和与之关联的对象(例如闭包)之间存在引用循环时,浏览器(通常是IE,尤其是旧版本)的内存泄漏。 在这些情况下,甚至可能不需要完整的参考计数scheme。
在NodeJS上运行JS时,可以考虑https://github.com/TooTallNate/node-weak 。
EcmaScript 6(ES Harmony)有一个WeakMap对象。 浏览器支持现代浏览器是相当不错的 (最后3个版本的Firefox,铬,甚至即将到来的IE版本支持它)。
真正的弱引用,不,还没有(但浏览器制造商正在看这个问题)。 但是这里有一个关于如何模拟弱引用的想法。
你可以build立一个caching来驱动你的对象。 当一个对象被存储时,caching保留了对象将占用多less内存的预测。 对于某些项目,如存储图像,这是直接解决的。 对于其他人来说,这会更困难。
当你需要一个对象的时候,然后问caching。 如果caching有对象,则返回。 如果不存在,那么该项目将被生成,存储并返回。
当预测内存总量达到一定水平时,由caching去除项模拟弱引用。 它会根据检索的频率来预测哪些项目的使用最less,加权的时间取决于它们的使用时间。 如果创build项目的代码作为闭包传递到caching中,也可以添加“计算”成本。 这将允许caching保留构build或生成的非常昂贵的项目。
删除algorithm是关键,因为如果你得到这个错误,那么你最终可能会删除最stream行的项目。 这会造成可怕的performance。
只要caching是永久引用存储对象的唯一对象,那么上述系统应该可以很好地工作,作为真正的弱引用的替代。
仅供参考; JavaScript没有,但ActionScript 3(也是ECMAScript)。 查看Dictionary的构造函数参数 。
使用caching机制来模拟一个弱引用,就像上面提到的JL235一样 ,是合理的。 如果弱引用本身存在,你会观察到这样的行为:
this.val = {}; this.ref = new WeakReference(this.val); ... this.ref.get(); // always returns val ... this.val = null; // no more references ... this.ref.get(); // may still return val, depending on already gc'd or not
而对于caching,你会发现:
this.val = {}; this.key = cache.put(this.val); ... cache.get(this.key); // returns val, until evicted by other cache puts ... this.val = null; // no more references ... cache.get(this.key); // returns val, until evicted by other cache puts
作为参考的持有者,您不应该对什么时候引用某个值做任何假设,这与使用caching没有任何区别
http://www.jibbering.com/faq/faq_notes/closures.html
ECMAScript使用自动垃圾收集。 该规范没有定义细节,留给实施者来解决,并且已知一些实现给它们的垃圾收集操作赋予非常低的优先级。 但是一般的想法是,如果一个对象变得不可参照(通过没有剩余的引用让它可以被执行代码访问),它就可以用于垃圾收集,并且在将来的某个点将被销毁,并且它所消耗的任何资源都将被释放并返回到系统重新使用。
退出执行上下文通常会是这种情况。 范围链结构,激活/variables对象以及在执行上下文中创build的任何对象(包括函数对象)将不再可访问,因此可用于垃圾回收。
意思是没有弱者只有那些不再可用的弱者。