简体   繁体   English

ES6 WeakMap 的实际用途是什么?

[英]What are the actual uses of ES6 WeakMap?

What are the actual uses of the WeakMap data structure introduced in ECMAScript 6? ECMAScript 6 中引入的WeakMap数据结构的实际用途是什么?

Since a key of a weak map creates a strong reference to its corresponding value, ensuring that a value which has been inserted into a weak map will never disappear as long as its key is still alive, it can't be used for memo tables, caches or anything else that you would normally use weak references, maps with weak values, etc. for.由于弱映射的键创建了对其对应值的强引用,确保插入弱映射的值只要其键还活着就永远不会消失,因此不能用于备忘录表,缓存或其他任何您通常会使用弱引用、具有弱值的映射等的东西。

It seems to me that this:在我看来,这是:

weakmap.set(key, value);

...is just a roundabout way of saying this: ...只是一种迂回的说法:

key.value = value;

What concrete use cases am I missing?我缺少哪些具体用例?

Fundamentally从根本上说

WeakMaps provide a way to extend objects from the outside without interfering with garbage collection. WeakMaps 提供了一种从外部扩展对象而不干扰垃圾收集的方法。 Whenever you want to extend an object but can't because it is sealed - or from an external source - a WeakMap can be applied.每当你想扩展一个对象但不能因为它是密封的 - 或者来自外部源 - 可以应用 Wea​​kMap。

A WeakMap is a map (dictionary) where the keys are weak - that is, if all references to the key are lost and there are no more references to the value - the value can be garbage collected. WeakMap 是一个映射(字典),其中是弱的——也就是说,如果对键的所有引用都丢失了并且没有更多对值的引用——该可以被垃圾收集。 Let's show this first through examples, then explain it a bit and finally finish with real use.让我们先通过例子来说明这一点,然后再解释一下,最后以实际使用结束。

Let's say I'm using an API that gives me a certain object:假设我使用的 API 为我提供了某个对象:

var obj = getObjectFromLibrary();

Now, I have a method that uses the object:现在,我有一个使用该对象的方法:

function useObj(obj){
   doSomethingWith(obj);
}

I want to keep track of how many times the method was called with a certain object and report if it happens more than N times.我想跟踪某个对象调用该方法的次数,并报告它发生的次数是否超过 N 次。 Naively one would think to use a Map:天真的人会认为使用 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);
}

This works, but it has a memory leak - we now keep track of every single library object passed to the function which keeps the library objects from ever being garbage collected.这有效,但它有内存泄漏 - 我们现在跟踪传递给函数的每个库对象,以防止库对象被垃圾收集。 Instead - we can use a WeakMap :相反 - 我们可以使用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);
}

And the memory leak is gone.内存泄漏消失了。

Use cases用例

Some use cases that would otherwise cause a memory leak and are enabled by WeakMap s include:一些会导致内存泄漏并由WeakMap启用的用WeakMap包括:

  • Keeping private data about a specific object and only giving access to it to people with a reference to the Map.保留有关特定对象的私有数据,并且只允许引用 Map 的人访问它。 A more ad-hoc approach is coming with the private-symbols proposal but that's a long time from now.私人符号提案将提供一种更临时的方法,但距离现在还有很长一段时间。
  • Keeping data about library objects without changing them or incurring overhead.保留有关库对象的数据而不更改它们或产生开销。
  • Keeping data about a small set of objects where many objects of the type exist to not incur problems with hidden classes JS engines use for objects of the same type.保留关于一小组对象的数据,其中存在许多该类型的对象,以免导致 JS 引擎用于相同类型对象的隐藏类出现问题。
  • Keeping data about host objects like DOM nodes in the browser.在浏览器中保存有关主机对象(如 DOM 节点)的数据。
  • Adding a capability to an object from the outside (like the event emitter example in the other answer).从外部向对象添加功能(如另一个答案中的事件发射器示例)。

Let's look at a real use来看看实际使用

It can be used to extend an object from the outside.它可用于从外部扩展对象。 Let's give a practical (adapted, sort of real - to make a point) example from the real world of Node.js.让我们从 Node.js 的真实世界中给出一个实际的(改编的,有点真实 - 说明一点)示例。

Let's say you're Node.js and you have Promise objects - now you want to keep track of all the currently rejected promises - however, you do not want to keep them from being garbage collected in case no references exist to them.假设你是 Node.js 并且你有Promise对象——现在你想要跟踪所有当前被拒绝的承诺——但是,你希望在不存在对它们的引用的情况下阻止它们被垃圾收集。

Now, you don't want to add properties to native objects for obvious reasons - so you're stuck.现在,你不想将属性添加到显而易见的原因,本地对象-这样你就完蛋了。 If you keep references to the promises you're causing a memory leak since no garbage collection can happen.如果您保留对承诺的引用,则会导致内存泄漏,因为不会发生垃圾收集。 If you don't keep references then you can't save additional information about individual promises.如果您不保留引用,则无法保存有关个人承诺的其他信息。 Any scheme that involves saving the ID of a promise inherently means you need a reference to it.任何涉及保存承诺 ID 的方案本质上都意味着您需要对它的引用。

Enter WeakMaps输入弱图

WeakMaps mean that the keys are weak. WeakMaps 意味着很弱。 There are no ways to enumerate a weak map or to get all its values.没有办法枚举弱映射或获取其所有值。 In a weak map, you can store the data based on a key and when the key gets garbage collected so do the values.在弱映射中,您可以根据键存储数据,当键被垃圾收集时,值也会被收集。

This means that given a promise you can store state about it - and that object can still be garbage collected.这意味着给定一个承诺,您可以存储有关它的状态 - 并且该对象仍然可以被垃圾收集。 Later on, if you get a reference to an object you can check if you have any state relating to it and report it.稍后,如果您获得对对象的引用,您可以检查是否有任何与它相关的状态并报告它。

This was used to implement unhandled rejection hooks by Petka Antonov as this :这被 P​​etka 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
});

We keep information about promises in a map and can know when a rejected promise was handled.我们将有关承诺的信息保存在地图中,并且可以知道何时处理了被拒绝的承诺。

This answer seems to be biased and unusable in a real world scenario.这个答案在现实世界中似乎有偏见且无法使用。 Please read it as is, and don't consider it as an actual option for anything else than experimentation请按原样阅读,不要将其视为实验以外的任何其他实际选择

A use case could be to use it as a dictionary for listeners, I have a coworker who did that.一个用例可能是将它用作听众的字典,我有一个同事就是这样做的。 It is very helpful because any listener is directly targetted with this way of doing things.这是非常有用的,因为任何听众都直接以这种做事方式为目标。 Goodbye listener.on .再见listener.on

But from a more abstract point of view, WeakMap is especially powerful to dematerialize access to basically anything, you don't need a namespace to isolate its members since it is already implied by the nature of this structure.但是从更抽象的角度来看, WeakMap特别强大,可以使对基本上任何事物的访问都去物质化,您不需要命名空间来隔离其成员,因为这种结构的性质已经暗示了这一点。 I'm pretty sure you could do some major memory improvements by replacing awkwards redundant object keys (even though deconstructing does the work for you).我很确定你可以通过替换笨拙的冗余对象键来做一些重大的内存改进(即使解构对你有用)。


Before reading what is next在阅读接下来的内容之前

I do now realize my emphasize is not exactly the best way to tackle the problem and as Benjamin Gruenbaum pointed out (check out his answer, if it's not already above mine :p), this problem could not have been solved with a regular Map , since it would have leaked, thus the main strength of WeakMap is that it does not interfere with garbage collection given that they do not keep a reference.我现在意识到我的强调并不是解决问题的最佳方法,正如本杰明·格鲁恩鲍姆指出的那样(看看他的答案,如果它不在我的上面:p),这个问题无法用普通的Map解决,因为它会泄漏,因此WeakMap的主要优点是它不会干扰垃圾收集,因为它们不保留引用。


Here is the actual code of my coworker (thanks to him for sharing)这是我同事的实际代码(感谢的分享)

Full source here , it's about listeners management I talked about above (you can also take a look at the specs )完整的源代码在这里,它是关于我上面谈到的监听器管理(你也可以看看规范

var listenableMap = new WeakMap();


export function getListenable (object) {
    if (!listenableMap.has(object)) {
        listenableMap.set(object, {});
    }

    return listenableMap.get(object);
}


export function getListeners (object, identifier) {
    var listenable = getListenable(object);
    listenable[identifier] = listenable[identifier] || [];

    return listenable[identifier];
}


export function on (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    listeners.push(listener);
}


export function removeListener (object, identifier, listener) {
    var listeners = getListeners(object, identifier);

    var index = listeners.indexOf(listener);
    if(index !== -1) {
        listeners.splice(index, 1);
    }
}


export function emit (object, identifier, ...args) {
    var listeners = getListeners(object, identifier);

    for (var listener of listeners) {
        listener.apply(object, args);
    }
}

WeakMap works well for encapsulation and information hiding WeakMap适用于封装和信息隐藏

WeakMap is only available for ES6 and above. WeakMap仅适用于 ES6 及更高版本。 A WeakMap is a collection of key and value pairs where the key must be an object. WeakMap是键值对的集合,其中键必须是对象。 In the following example, we build a WeakMap with two items:在以下示例中,我们构建了一个包含两个项的WeakMap

var map = new WeakMap();
var pavloHero = {first: "Pavlo", last: "Hero"};
var gabrielFranco = {first: "Gabriel", last: "Franco"};
map.set(pavloHero, "This is Hero");
map.set(gabrielFranco, "This is Franco");
console.log(map.get(pavloHero));//This is Hero

We used the set() method to define an association between an object and another item (a string in our case).我们使用set()方法来定义一个对象和另一个项目(在我们的例子中是一个字符串)之间的关联。 We used the get() method to retrieve the item associated with an object.我们使用get()方法来检索与对象关联的项目。 The interesting aspect of the WeakMap s is the fact that it holds a weak reference to the key inside the map. WeakMap的有趣之WeakMap在于它持有对地图内键的弱引用。 A weak reference means that if the object is destroyed, the garbage collector will remove the entire entry from the WeakMap , thus freeing up memory.弱引用意味着如果对象被销毁,垃圾收集器将从WeakMap删除整个条目,从而释放内存。

var TheatreSeats = (function() {
  var priv = new WeakMap();
  var _ = function(instance) {
    return priv.get(instance);
  };

  return (function() {
      function TheatreSeatsConstructor() {
        var privateMembers = {
          seats: []
        };
        priv.set(this, privateMembers);
        this.maxSize = 10;
      }
      TheatreSeatsConstructor.prototype.placePerson = function(person) {
        _(this).seats.push(person);
      };
      TheatreSeatsConstructor.prototype.countOccupiedSeats = function() {
        return _(this).seats.length;
      };
      TheatreSeatsConstructor.prototype.isSoldOut = function() {
        return _(this).seats.length >= this.maxSize;
      };
      TheatreSeatsConstructor.prototype.countFreeSeats = function() {
        return this.maxSize - _(this).seats.length;
      };
      return TheatreSeatsConstructor;
    }());
})()

𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮 𝗠𝗲𝘁𝗮𝗱𝗮𝘁𝗮

Weak Maps can be used to store metadata about DOM elements without interfering with garbage collection or making coworkers mad at your code. Weak Maps 可用于存储有关 DOM 元素的元数据,而不会干扰垃圾收集或让同事对您的代码感到生气。 For example, you could use them to numerically index all of the elements in a webpage.例如,您可以使用它们对网页中的所有元素进行数字索引。

𝗪𝗶𝘁𝗵𝗼𝘂𝘁 𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗼𝗿 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀: 𝗪𝗶𝘁𝗵𝗼𝘂𝘁𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀𝗼𝗿𝗪𝗲𝗮𝗸𝗦𝗘:

 var elements = document.getElementsByTagName('*'), i = -1, len = elements.length; while (++i !== len) { // Production code written this poorly makes me want to cry: elements[i].lookupindex = i; elements[i].elementref = []; elements[i].elementref.push( elements[(i * i) % len] ); } // Then, you can access the lookupindex's // For those of you new to javascirpt, I hope the comments below help explain // how the ternary operator (?:) works like an inline if-statement document.write(document.body.lookupindex + '<br />' + ( (document.body.elementref.indexOf(document.currentScript) !== -1) ? // if(document.body.elementref.indexOf(document.currentScript) !== -1){ "true" : // } else { "false" ) // } );

𝗨𝘀𝗶𝗻𝗴 𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗮𝗻𝗱 𝗪𝗲𝗮𝗸𝗦𝗲𝘁𝘀: 𝗨𝘀𝗶𝗻𝗴 𝗪𝗲𝗮𝗸𝗠𝗮𝗽𝘀 𝗮𝗻𝗱 𝗪𝗲𝗮𝗸𝗦𝗲𝘁

 var DOMref = new WeakMap(), __DOMref_value = Array, __DOMref_lookupindex = 0, __DOMref_otherelement = 1, elements = document.getElementsByTagName('*'), i = -1, len = elements.length, cur; while (++i !== len) { // Production code written this well makes me want to 😊: cur = DOMref.get(elements[i]); if (cur === undefined) DOMref.set(elements[i], cur = new __DOMref_value) cur[__DOMref_lookupindex] = i; cur[__DOMref_otherelement] = new WeakSet(); cur[__DOMref_otherelement].add( elements[(i * i) % len] ); } // Then, you can access the lookupindex's cur = DOMref.get(document.body) document.write(cur[__DOMref_lookupindex] + '<br />' + ( cur[__DOMref_otherelement].has(document.currentScript) ? // if(cur[__DOMref_otherelement].has(document.currentScript)){ "true" : // } else { "false" ) // } );

𝗧𝗵𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲 𝗧𝗵𝗲 𝗗𝗶𝗳𝗳𝗲𝗿𝗲𝗻𝗰𝗲

The difference may look negligible, aside from the fact that the weakmap version is longer, however there is a major difference between the two pieces of code shown above.除了弱图版本更长这一事实之外,差异可能看起来可以忽略不计,但是上面显示的两段代码之间存在重大差异。 In the first snippet of code, without weak maps, the piece of code stores references every which way between the DOM elements.在第一段代码中,没有弱映射,这段代码在 DOM 元素之间的每一个地方存储引用。 This prevents the DOM elements from being garbage collected.这可以防止 DOM 元素被垃圾收集。 (i * i) % len may seem like an oddball that nobody would use, but think again: plenty of production code has DOM references that bounce all over the document. (i * i) % len可能看起来像一个没人会使用的古怪,但再想一想:大量的生产代码都有 DOM 引用,这些引用会在整个文档中反弹。 Now, for the second piece of code, because all the references to the elements are weak, when you a remove a node, the browser is able to determine that the node is not used (not able to be reached by your code), and thus delete it from memory.现在,对于第二段代码,因为对元素的所有引用都很弱,当您删除一个节点时,浏览器能够确定该节点未被使用(您的代码无法访问),并且因此将其从内存中删除。 The reason for why you should be concerned about memory usage, and memory anchors (things like the first snippet of code where unused elements are held in memory) is because more memory usage means more browser GC-attempts (to try to free up memory to avert a browser crash) means slower browsing experience and sometimes a browser crash.您应该关注内存使用情况和内存锚点(例如未使用元素保存在内存中的第一个代码片段)的原因是因为更多的内存使用量意味着更多的浏览器 GC 尝试(尝试释放内存以避免浏览器崩溃)意味着更慢的浏览体验,有时会导致浏览器崩溃。

As for a polyfill for these, I would recommend my own library ( found here @ github ).至于这些的 polyfill,我会推荐我自己的库( 在这里找到 @github )。 It is a very lightweight library that will simply polyfill it without any of the way-overly-complex frameworks you might find in other polyfills.它是一个非常轻量级的库,可以简单地对其进行 polyfill,而无需您可能在其他 polyfill 中找到的任何过于复杂的框架。

~ Happy coding! ~快乐编码!

I use WeakMap for the cache of worry-free memoization of functions that take in immutable objects as their parameter.我使用WeakMap来缓存以不可变对象作为参数的函数的无忧记忆。

Memoization is fancy way of saying "after you compute the value, cache it so you don't have to compute it again". Memoization 是一种奇特的说法,即“在计算完值后,将其缓存起来,这样您就不必再次计算它了”。

Here's an example:下面是一个例子:

 // using immutable.js from here https://facebook.github.io/immutable-js/ const memo = new WeakMap(); let myObj = Immutable.Map({a: 5, b: 6}); function someLongComputeFunction (someImmutableObj) { // if we saved the value, then return it if (memo.has(someImmutableObj)) { console.log('used memo!'); return memo.get(someImmutableObj); } // else compute, set, and return const computedValue = someImmutableObj.get('a') + someImmutableObj.get('b'); memo.set(someImmutableObj, computedValue); console.log('computed value'); return computedValue; } someLongComputeFunction(myObj); someLongComputeFunction(myObj); someLongComputeFunction(myObj); // reassign myObj = Immutable.Map({a: 7, b: 8}); someLongComputeFunction(myObj);
 <script src="https://cdnjs.cloudflare.com/ajax/libs/immutable/3.8.1/immutable.min.js"></script>

A few things to note:需要注意的几点:

  • Immutable.js objects return new objects (with a new pointer) when you modify them so using them as keys in a WeakMap is guarantees the same computed value. Immutable.js 对象在修改它们时返回新对象(带有新指针),因此将它们用作 WeakMap 中的键可以保证相同的计算值。
  • The WeakMap is great for memos because once the object (used as the key) gets garbage collected, so does the computed value on the WeakMap. WeakMap 非常适合备忘录,因为一旦对象(用作键)被垃圾回收,WeakMap 上的计算值也会被回收。

I have this simple feature based use case/Example for WeakMaps.我有这个基于简单功能的 WeakMaps 用例/示例。

MANAGE A COLLECTION OF USERS管理用户集合

I started off with a User Object whose properties include a fullname , username , age , gender and a method called print which prints a human readable summary of the other properties.我从一个User对象开始,它的属性包括fullname usernameusernameagegender和一个名为print的方法,该方法print其他属性的人类可读摘要。

/**
Basic User Object with common properties.
*/
function User(username, fullname, age, gender) {
    this.username = username;
    this.fullname = fullname;
    this.age = age;
    this.gender = gender;
    this.print = () => console.log(`${this.fullname} is a ${age} year old ${gender}`);
}

I then added a Map called users to keep a collection of multiple users which are keyed by username .然后我添加了一个名为users的 Map 来保存由username键的多个用户的集合。

/**
Collection of Users, keyed by username.
*/
var users = new Map();

Addition of the Collection also required helper functions to add, get, delete a User and even a function to print all the users for sake of completeness.添加集合还需要辅助函数来添加、获取、删除用户,甚至为了完整起见打印所有用户的函数。

/**
Creates an User Object and adds it to the users Collection.
*/
var addUser = (username, fullname, age, gender) => {
    let an_user = new User(username, fullname, age, gender);
    users.set(username, an_user);
}

/**
Returns an User Object associated with the given username in the Collection.
*/
var getUser = (username) => {
    return users.get(username);
}

/**
Deletes an User Object associated with the given username in the Collection.
*/
var deleteUser = (username) => {
    users.delete(username);
}

/**
Prints summary of all the User Objects in the Collection.
*/
var printUsers = () => {
    users.forEach((user) => {
        user.print();
    });
}

With all of the above code running in, say NodeJS , only the users Map has the reference to the User Objects within the entire process.上面的所有代码都运行在NodeJS 中,在整个过程中,只有users Map 具有对用户对象的引用。 There is no other reference to the individual User Objects.没有对单个用户对象的其他引用。

Running this code an interactive NodeJS shell, just as an Example I add four users and print them:在交互式 NodeJS shell 中运行此代码,作为示例,我添加了四个用户并打印它们: 添加和打印用户

ADD MORE INFO TO USERS WITHOUT MODIFYING EXISTING CODE在不修改现有代码的情况下向用户添加更多信息

Now say a new feature is required wherein each users Social Media Platform (SMP) links need to be tracked along with the User Objects.现在说需要一个新功能,其中每个用户的社交媒体平台 (SMP) 链接需要与用户对象一起跟踪。

The key here is also that this feature must be implemented with minimum intervention to the existing code.这里的关键还在于必须在对现有代码的干预最少的情况下实现此功能。

This is possible with WeakMaps in the following manner. WeakMaps 可以通过以下方式实现这一点。

I add three separate WeakMaps for Twitter, Facebook, LinkedIn.我为 Twitter、Facebook、LinkedIn 添加了三个单独的 WeakMap。

/*
WeakMaps for Social Media Platforms (SMPs).
Could be replaced by a single Map which can grow
dynamically based on different SMP names . . . anyway...
*/
var sm_platform_twitter = new WeakMap();
var sm_platform_facebook = new WeakMap();
var sm_platform_linkedin = new WeakMap();

A helper function, getSMPWeakMap is added simply to return the WeakMap associated with the given SMP name.添加一个辅助函数getSMPWeakMap只是为了返回与给定 SMP 名称关联的 WeakMap。

/**
Returns the WeakMap for the given SMP.
*/
var getSMPWeakMap = (sm_platform) => {
    if(sm_platform == "Twitter") {
        return sm_platform_twitter;
    }
    else if(sm_platform == "Facebook") {
        return sm_platform_facebook;
    }
    else if(sm_platform == "LinkedIn") {
        return sm_platform_linkedin;
    }
    return undefined;
}

A function to add a users SMP link to the given SMP WeakMap.将用户 SMP 链接添加到给定 SMP WeakMap 的函数。

/**
Adds a SMP link associated with a given User. The User must be already added to the Collection.
*/
var addUserSocialMediaLink = (username, sm_platform, sm_link) => {
    let user = getUser(username);
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    if(user && sm_platform_weakmap) {
        sm_platform_weakmap.set(user, sm_link);
    }
}

A function to print only the users who are present on the given SMP.仅打印给定 SMP 上存在的用户的功能。

/**
Prints the User's fullname and corresponding SMP link of only those Users which are on the given SMP.
*/
var printSMPUsers = (sm_platform) => {
    let sm_platform_weakmap = getSMPWeakMap(sm_platform);
    console.log(`Users of ${sm_platform}:`)
    users.forEach((user)=>{
        if(sm_platform_weakmap.has(user)) {
            console.log(`\t${user.fullname} : ${sm_platform_weakmap.get(user)}`)
        }
    });
}

You can now add SMP links for the users, also with the possibility of each user having a link on multiple SMPs.您现在可以为用户添加 SMP 链接,还可以让每个用户在多个 SMP 上拥有一个链接。

...continuing with the earlier Example, I add SMP links to the users, multiple links for users Bill and Sarah and then print the links for each SMP separately: ...继续前面的示例,我向用户添加 SMP 链接,为用户 Bill 和 Sarah 添加多个链接,然后分别打印每个 SMP 的链接: 向用户添加 SMP 链接并显示它们

Now say a User is deleted from the users Map by calling deleteUser .现在说通过调用deleteUserusers映射中删除一个用户。 That removes the only reference to the User Object.这将删除对用户对象的唯一引用。 This in turn will also clear out the SMP link from any/all of the SMP WeakMaps (by Garbage Collection) as without the User Object there is no way to access any of its SMP link.这反过来也会从任何/所有 SMP WeakMaps(通过垃圾收集)清​​除 SMP 链接,因为没有用户对象,就无法访​​问其任何 SMP 链接。

...continuing with the Example, I delete user Bill and then print out the links of the SMPs he was associated with: ...继续示例,我删除用户Bill ,然后打印出与他关联的 SMP 的链接:

从地图中删除用户 Bill 也会删除 SMP 链接

There is no requirement of any additional code to individually delete the SMP link separately and the existing code before this feature was not modified in anyway.不需要任何额外的代码来单独删除 SMP 链接,并且在此功能之前的现有代码没有进行任何修改。

If there is any other way to add this feature with/without WeakMaps please feel free to comment.如果有任何其他方式可以在有/没有 WeakMaps 的情况下添加此功能,请随时发表评论。

I think it's very helpful for checking a connection income in applications socket.我认为这对于检查应用程序套接字中的连接收入非常有帮助。 The other case, the 'Weak Collection' are useful: https://javascript.info/task/recipients-read另一种情况,“弱集合”很有用: https : //javascript.info/task/recipients-read

WEAKMAP : keep in mind weakMap is all about memory allocation and garbage collection and only related to key of object type in javascript when u store values in key-value pair array, map, set, etc... a memory allocated to all key-value pair and this memory will not be free even if you delete or set null to that key consider this as a strongmap keys are strongly attache to memory below is example WEAKMAP :请记住,weakMap 是关于内存分配和垃圾收集的,并且仅当您将值存储在键值对数组、映射、集合等中时,才与 JavaScript 中对象类型的键有关......分配给所有键的内存-值对,即使您删除该键或将 null 设置为该键,该内存也不会空闲,请考虑这是一个强映射键强烈附加到内存下面的示例

let john = { name: "yusuf" };

let map = new Map();
map.set(yusuf, "xyz"); //here "yusuf" is the key and "xyz" is value

yusuf= null; // overwrite the reference

// the object previously referenced by yusuf is stored inside the array
// therefore it won't be garbage-collected
// we can get it using map.keys()

but this is not the case with weakMap in here memory will be free但这里的weakMap 情况并非如此,内存将是免费的

let john = { name: "yusuf" };

let map = new WeakMap();
map.set(yusuf, "...");

yusuf= null; // overwrite the reference

// yusuf is removed from memory!

USE CASE : you will use it in javascript where u want to manage memory in more efficient way用例:您将在 javascript 中使用它,您希望以更有效的方式管理内存

If we're working with an object that “belongs” to another code, maybe even a third-party library, and would like to store some data associated with it, that should only exist while the object is alive – then WeakMap is exactly what's needed.如果我们正在处理一个“属于”另一个代码的对象,甚至可能是第三方库,并且想要存储一些与之相关的数据,那么它应该只在对象存在时才存在——那么 WeakMap 正是需要。

We put the data to a WeakMap, using the object as the key, and when the object is garbage collected, that data will automatically disappear as well.我们将数据放到 WeakMap 中,使用对象作为键,当对象被垃圾回收时,该数据也会自动消失。

weakMap.set(yusuf, "secret documents");
// if yusuf dies, secret documents will be destroyed automatically

I took reference from this great article : https://javascript.info/weakmap-weakset我参考了这篇很棒的文章: https : //javascript.info/weakmap-weakset

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM