WeakMap
ECMAScript 6中引入的数据结构的实际用途是什么?
由于弱映射的键会对其对应的值建立强引用,因此确保只要弱键仍处于活动状态,插入到弱映射中的值就 永远不会
消失,因此不能将其用于备忘录表,缓存或通常使用弱引用,具有弱值的映射等的其他任何内容。
在我看来,这是:
weakmap.set(key, value);
…只是一种回旋的说法:
key.value = value;
我缺少哪些具体用例?
WeakMaps提供了一种从外部扩展对象而不干扰垃圾回收的方法。
每当您想扩展对象但由于密封而不能扩展对象时(或者从外部源扩展)时,都可以应用WeakMap。
WeakMap是 键 弱的映射(字典),也就是说,如果丢失了对 键的 所有引用,并且不再有对该值的引用,则可以对 值
进行垃圾回收。让我们首先通过示例展示它,然后进行一些解释,最后完成实际使用。
假设我使用的API给了我一个特定的对象:
var obj = getObjectFromLibrary();
现在,我有一个使用该对象的方法:
function useObj(obj){
doSomethingWith(obj);
}
我想跟踪用某个对象调用该方法的次数,并报告该方法是否发生了N次以上。天真的会想到使用Map:
var map = new Map(); // maps can have object keys
function useObj(obj){
doSomethingWith(obj);
var called = map.get(obj) || 0;
called++; // called one more time
if(called > 10) report(); // Report called more than 10 times
map.set(obj, called);
}
这可行,但是会发生内存泄漏-我们现在跟踪传递给该函数的每个库对象,从而避免垃圾回收。相反-我们可以使用WeakMap
:
var map = new WeakMap(); // create a weak map
function useObj(obj){
doSomethingWith(obj);
var called = map.get(obj) || 0;
called++; // called one more time
if(called > 10) report(); // Report called more than 10 times
map.set(obj, called);
}
并且内存泄漏消失了。
可能会导致内存泄漏并由启用的一些用例WeakMap
包括:
它可用于从外部扩展对象。让我们从Node.js的真实世界中给出一个实用的(经过改编的,真实的)实例。
比方说,你的Node.js,你有Promise
对象-现在你想跟踪所有当前被拒绝承诺-然而,你 不 希望让他们被的情况下,垃圾收集没有引用存在于他们。
现在,你 不 希望将属性添加到显而易见的原因,本地对象-
这样你就完蛋了。如果保留对Promise的引用,则将导致内存泄漏,因为不会发生垃圾回收。如果您不保留引用,那么您将无法保存有关单个承诺的其他信息。任何涉及保存承诺ID的方案本质上都意味着您需要对其进行引用。
WeakMaps表示 键 很弱。无法枚举弱映射或获取其所有值。在弱映射中,您可以基于密钥存储数据,并且在密钥被垃圾回收时也可以存储值。
这意味着只要有一个承诺,您就可以存储有关它的状态-
而且该对象仍可以被垃圾回收。稍后,如果您获得对对象的引用,则可以检查是否具有与该对象有关的任何状态并报告该对象。
Petka Antonov用来实现未处理的拒绝挂钩,如下所示:
process.on('unhandledRejection', function(reason, p) {
console.log("Unhandled Rejection at: Promise ", p, " reason: ", reason);
// application specific logging, throwing an error, or other logic here
});
我们将有关诺言的信息保存在地图中,并且可以知道何时处理了被拒绝的诺言。
ECMAScript 6中引入的数据结构的实际用途是什么? 由于弱映射的键创建对其对应值的强引用,确保插入到弱映射中的值在其键仍处于活动状态时永远不会消失,因此它不能用于备注表、缓存或您通常使用弱引用、具有弱值的映射等的任何其他内容。 在我看来: …只是一种迂回的说法: 我缺少哪些具体的用例?
问题内容: 我正在尽最大的努力来解决JavaScript闭包问题。 通过返回一个内部函数,我可以访问其直接父级中定义的任何变量。 这对我有用吗?也许我还没有完全解决这个问题。我在网上看到的大多数示例都没有提供任何真实的代码,只是模糊的示例。 有人可以告诉我现实世界中使用闭包吗? 例如这个吗? 问题答案: 我用闭包来做类似的事情: 如您所见,现在有一个对象,带有一个方法()调用,该方法仅存在于闭包内
当function.identity()返回与它接收到的相同的东西时,我为什么要使用它,而不使用输入或以某种方式修改输入? 这一定有一些实际的用法,但我不知道。
问题内容: 在Java中,接口的任何使用都由抽象类实现。我知道接口的一个优点是,如果我们实现一个接口,那么我们也可以扩展另一个类。Java接口还有其他用途或优点吗? 问题答案: 您喜欢什么:在一个Abstract类中成千上万个抽象方法并继承该类,或者为特定的抽象方法创建尽可能多的接口,并通过继承所需的任意数量的接口来仅使用您想要的那些方法… 因此,仅通过继承特定接口使用该方法即可,如果您要继承类,
问题内容: 我知道Javassist是一个Java库,提供了一种操作应用程序的Java字节码的方法。 好的,但是为什么我们需要操纵字节码? 有什么真实的例子吗?任何真正的应用程序,javassist在哪里使用? 问题答案: 一个常见的应用是在运行时生成代理类,即在运行时创建一个子类,以拦截所有方法调用。例子: Hibernate 使用代理来拦截对实体的方法调用以实现延迟加载,即,在首次访问对象时从
问题内容: 我有点理解AtomicInteger和其他Atomic变量允许并发访问。但是在什么情况下通常使用此类? 问题答案: 有两个主要用途: 作为可以同时被多个线程使用的原子计数器(,等) 作为支持比较和交换指令()来实现非阻塞算法的原语。 这是BrianGöetz的中的非阻塞随机数生成器的示例: 如你所见,它的工作原理与几乎相同incrementAndGet(),但是执行任意计算(calcu