Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/javascript/410.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Javascript ES6集、WeakSet、Map和WeakMap_Javascript_Ecmascript 6 - Fatal编程技术网

Javascript ES6集、WeakSet、Map和WeakMap

Javascript ES6集、WeakSet、Map和WeakMap,javascript,ecmascript-6,Javascript,Ecmascript 6,关于map和弱map已经有一些问题了,比如:但是我想问,在什么情况下我应该支持使用这些数据结构?或者,当我偏爱其中一个时,我应该考虑什么 数据结构示例来自: 奖金。上面哪种数据结构将产生相同/相似的结果:let hash=object.create(null);散列[索引]=某物本规范的第1部分介绍了这一点: 如果用作WeakMap键/值对的键的对象只能通过遵循从该WeakMap中开始的引用链来访问,则该键/值对不可访问,并自动从WeakMap中删除 因此,弱映射中的条目,如果它们的键没有被其他

关于map和弱map已经有一些问题了,比如:但是我想问,在什么情况下我应该支持使用这些数据结构?或者,当我偏爱其中一个时,我应该考虑什么

数据结构示例来自:

奖金。上面哪种数据结构将产生相同/相似的结果:
let hash=object.create(null);散列[索引]=某物

本规范的第1部分介绍了这一点:

如果用作
WeakMap
键/值对的键的对象只能通过遵循从该
WeakMap
中开始的引用链来访问,则该键/值对不可访问,并自动从
WeakMap
中删除

因此,弱映射中的条目,如果它们的键没有被其他任何东西引用,将在某个时候被垃圾收集回收

相反,
映射
持有对其键的强引用,如果映射是唯一引用键的对象,则可以防止它们被垃圾收集

MDN:

WeakMap
中的键被弱持有。这意味着,如果没有对键的其他强引用,则垃圾收集器将从
WeakMap
中删除整个条目

WeakSet
也做了同样的事情

…在哪种情况下我应该支持使用这种数据结构

在任何情况下,如果您不希望您有一个映射/集使用一个键来防止该键被垃圾收集,则可以使用该键。以下是一些例子:

  • 拥有对实例真正私有的特定于实例的信息,如下所示:(注意:这个示例来自2015年,远在我们选择之前。在2021年,我将使用私有字段。)

    let Thing=(()=>{
    var privateData=new WeakMap();
    阶级事务{
    构造函数(){
    privateData[此]={
    傅:“一些价值”
    };
    }
    doSomething(){
    log(privateData[this].foo);
    }
    }
    归还物;
    })();
    
    作用域函数之外的代码无法访问
    privateData
    中的数据。该数据由实例本身设置密钥。如果没有
    WeakMap
    ,您就不会这样做,因为这会导致内存泄漏,您的
    东西
    实例将永远无法清理。但是
    WeakMap
    只保存弱引用,因此,如果使用
    对象的代码使用了它并释放了对实例的引用,那么
    WeakMap
    不会阻止实例被垃圾收集;相反,实例键入的条目将从映射中删除

  • 保存您不控制的对象的信息。假设您从某个API获得一个对象,并且需要记住关于该对象的一些附加信息。您可以将属性添加到对象本身(如果对象未密封),但将属性添加到您无法控制的对象只会带来麻烦。相反,您可以使用对象设置关键帧的
    WeakMap
    来存储额外信息

  • WeakSet
    的一个用例是跟踪或标记:假设在“使用”对象之前,您需要知道该对象过去是否“使用过”,但不将其存储为对象上的标志(可能是因为如果它是对象上的标志,其他代码可以看到它)[虽然您可以使用私有字段来防止这种情况];或者因为它不是您的对象[因此私有字段没有帮助]。例如,这可能是某种一次性访问令牌。
    WeakSet
    是一种简单的方法,无需强制对象留在内存中

  • 上面哪种数据结构会产生相同/相似的结果:
    let hash=Object.create(null);hash[index]=something;


    这将最接近
    映射
    ,因为字符串
    索引
    (属性名称)将由对象中的强引用保存(如果没有其他引用它,它及其关联属性将不会被回收)。

    “奖金”每个问题问一个问题。仅在地图上。特别是与生活相关的例子:……还有。我真的倾向于以重复的形式结束。这不仅仅是关于弱点,是关于什么时候偏爱一个而不是其他,不是重复…@BergiI这周一直在学习ES6/TypeScript,这一定是我第30次遇到并受益从你的回答中,我已经到了我现在希望被接受的答案是你的地步。感谢你投入如此多的时间和精力来帮助这个社区和其他开发人员。@LogicalBranch-天哪,谢谢!我真的很感谢你花时间说这些。:-)
    // Sets
    var s = new Set();
    s.add("hello").add("goodbye").add("hello");
    s.size === 2;
    s.has("hello") === true;
    
    // Maps
    var m = new Map();
    m.set("hello", 42);
    m.set(s, 34);
    m.get(s) == 34;
    
    // Weak Maps
    var wm = new WeakMap();
    wm.set(s, { extra: 42 });
    wm.size === undefined
    
    // Weak Sets
    var ws = new WeakSet();
    ws.add({ data: 42 });
    // Because the added object has no other references, it will not be held in the set