V2EX = way to explore
V2EX 是一个关于分享和探索的地方
现在注册
已注册用户请  登录
推荐关注
Meteor
JSLint - a JavaScript code quality tool
jsFiddle
D3.js
WebStorm
推荐书目
JavaScript 权威指南第 5 版
Closure: The Definitive Guide
ghostheaven
V2EX  ›  JavaScript

ES6 的 WeakSet 的 has 有什么用

  •  
  •   ghostheaven · 2016-07-18 13:09:46 +08:00 · 3661 次点击
    这是一个创建于 3083 天前的主题,其中的信息可能已经有所发展或是发生改变。

    ES6 的 WeakSet 不能遍历内部的对象,内部的对象也不保持引用,所以 GC 的时候会删除,而且 key 一定是对象不能是简单类型。

    那么问题来了,比如 WeakSet 的 has(key)这个方法,假如 key 被 GC 了,我根本不可能拿到这个 key 了,怎么可能再传给 has 这个方法呢。

    求指教。。。

    第 1 条附言  ·  2016-07-18 15:35:05 +08:00
    我想做一个 int->Object 的 WeakMap , Object 随系统回收。本来想如果 WeakMap 查不到这个 id 就认为对象被回收了,就忽略掉。后来发现 WeakMap 要求 key 只能是对象,那就考虑 WeakSet ,假如 WeakSet 遍历,看看有没有对应 id 的 Object 就好了。然后发现 WeakSet 不能遍历。。。。

    我只想说从来没有见过这么鸡肋的 Weak 类设计, ES 标准组都是吃屎的么。
    13 条回复    2016-07-19 07:19:36 +08:00
    BOYPT
        1
    BOYPT  
       2016-07-18 13:28:42 +08:00
    你还能传给 has 说明没有被 GC (
    ghostheaven
        2
    ghostheaven  
    OP
       2016-07-18 13:49:40 +08:00 via Android
    @BOYPT 所以啊, weakset 跟 set 也就一样了
    BOYPT
        3
    BOYPT  
       2016-07-18 14:09:25 +08:00
    @ghostheaven 我写的 js 还没用到这些高端类型;
    不过我写 python 的时候用过 weakref.WeakKeyDictionary ,当这个 dict 里面的对象在其他地方被回收了之后,这个 dict 里面就没有这个对象了。
    用 Dict 可以不行,一直存在。
    SoloCompany
        4
    SoloCompany  
       2016-07-18 14:12:29 +08:00 via iPhone
    为什么没有用,你拿着这个对象只说明它没被回收,不等于有曾经被放进去过
    ghostheaven
        5
    ghostheaven  
    OP
       2016-07-18 15:21:49 +08:00 via Android
    @SoloCompany 请问怎样使用 has 这个方法,请举个例子
    ghostheaven
        6
    ghostheaven  
    OP
       2016-07-18 15:40:59 +08:00
    @BOYPT 以前写过 Java , Java 的 Weak 类也不要求 key 必须是对象,而且可以遍历, Python 的我看了一下也是类似的。真没见过 ES 这样设计 Weak 类的,脑子注水了么。
    EPr2hh6LADQWqRVH
        7
    EPr2hh6LADQWqRVH  
       2016-07-18 15:52:38 +08:00
    我感觉 LZ 你这个思路有问题, Week 系列的想法是在原本这些东西的基础上所操纵的东西引用没有计数,因为元素的引用没计数,所以导致了一些问题,比如不能用 Str 作 key ,不能遍历等等,原有类的功能还是尽可能保留的,能明白我的意思么。。
    ghostheaven
        8
    ghostheaven  
    OP
       2016-07-18 15:55:54 +08:00
    @avastms 我不明白 key 要求必须是 Object ,而且不能遍历。 Map 和 Set 都是可以遍历的,这个重要的功能就没有。
    SoloCompany
        9
    SoloCompany  
       2016-07-18 18:58:01 +08:00
    @ghostheaven 你是不是理解错了,请回去再看一次 Java 的 WeakHashMap 的文档,上面写的非常清楚,是 weak keys 而不是 values
    SoloCompany
        10
    SoloCompany  
       2016-07-18 19:00:17 +08:00
    weak map 本来就不是设计给这种性质的 cache 用的,请回去多看一次 LinkedHashCache 的文档,有教你怎么利用 LinkedHashCache 来实现一个 LILO 或者 LIFO 的 cache 的, weak map 从来就不是设计给你自以为是的场景使用的,还口出不逊,真是智商堪忧
    ghostheaven
        11
    ghostheaven  
    OP
       2016-07-18 19:46:03 +08:00 via Android
    @SoloCompany ok. Java 的 WeakHashMap 确实是 weak key ,但是没有限定必须是 object ,而且判断等价可以重载 isEqual ,而且可以遍历。 ES 都没有。
    SoloCompany
        12
    SoloCompany  
       2016-07-18 21:22:49 +08:00
    @ghostheaven 本来想说 RTFM 的,但觉得还是解释一下比较好。你说的没错, js 不能和 Java 相比,因为它本来就是个残缺的语言,虽然有了 WeakMap 但因为缺少 WeakReference 以及真正意义的 HashMap , WeakMap 是不能用来实现支持 gc cache 的,要想自己实现 cache ,还是只能自己去维护生命周期吧,因为 WeakMap 本来就不是为 cache 而设计的,可以参考 http://stackoverflow.com/a/25572082/2465785 以及 design goal http://stackoverflow.com/a/29416340/2465785

    Java 的 weakmap 设计用途也是类似的,只不过文档也提到, WeakHashMap 除了主要用于设计给 identity equaly 的 key 也可以和普通的 value equaly 的 key 配合使用如 String 就是说也可以用作 cache ,但你需要很小心的使用,否则回收根本不可能起作用,因为这本来就不是设计场景
    ghostheaven
        13
    ghostheaven  
    OP
       2016-07-19 07:19:36 +08:00 via Android
    @SoloCompany js 本来残我承认, 7 天做出来的语言嘛。但 Weak 类可是最近这几年标准组搞出来的,起码参考一下现有 Weak 类的设计和使用场景吧。况且现在还有人觉得 JS 只是给网页做点花哨的小功能的玩具吗,没有什么理由认为在 JS 上不会出现其他语言出现的使用场景。
    ps: Java 有 WeakReference 只是这一种语言的实现而已, Python 的 Weak 类也没有 WeakReference ,不是一样可以实现。
    关于   ·   帮助文档   ·   博客   ·   API   ·   FAQ   ·   实用小工具   ·   5613 人在线   最高记录 6679   ·     Select Language
    创意工作者们的社区
    World is powered by solitude
    VERSION: 3.9.8.5 · 24ms · UTC 03:22 · PVG 11:22 · LAX 19:22 · JFK 22:22
    Developed with CodeLauncher
    ♥ Do have faith in what you're doing.