最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • Map Set WeakMap WeakSet 场景

    正文概述 掘金(昭光)   2021-02-04   505

    Set 和 Map 是 ES6 新增的数据结构。成员的值都是唯一的、无重复的。

    1、Set 元素唯一

    Set 对象是值的集合,且元素是唯一的,类比数组。

    留意下: 唯一值的判断和 === 的运算符算法是不一样的。-0 +0 是两个值,-0\+0 是相同的。NaN之间视为相同的值,

    consturctor 上的api

    Map Set WeakMap WeakSet 场景

    • add 返回Set对象,所以可以链式添加 xx.add().add(3) 添加元素
    • delete 返回Boolean 结果
    • 这里的entries 返回一个新的迭代器对象,每个键和值相等。
    • Set.prototype.forEach(callbackFn[, thisArg]) 如果提供了thisArg参数,回调中的this会是这个参数。

    有迭代器对象的,都可以用for ... of 进行遍历

    for (let item of mySet) console.log(item);
    // key === value 每个键和值相等
    for(let [key, value] of mySet.entries()) console.log(key, value)
    

    set 和Array 的互换

    let set = new Set([1,2,3])
    [...set] // [1,2,3]
    Array.from(set)
    

    求交集、并集、差集, 数组去重

    // 交集
    let intersection = new Set([...set1].filter(x => set2.has(x)))
    let union = new Set([...set1, ...set2])
    let difference = new Set([...set1].filter(x => !set2.has(x)))
    

    如果Set 传入一个字符串,则会拆开 //

    Array.from(new Set('Hello')) // ['H', 'e', 'l', 'l', 'o']
    

    如何修改?

    2、Map 保存键值对,且有插入顺序

    Map 对象保存键值对,并且能够记住键的原始插入顺序。任何值(对象或者原始值) 都可以作为一个键或一个值。 键值相等的判断和set 上是一致的。

    Map 和 Object 的比较:

    对比选项MapObject
    键名冲突Map默认没有显式的键容易与原型的键名产生冲突键的类型Map的键可以是任意值,函数、对象或任意基本类型object 必须是string 或 symbolsize返回键值对数量object keys 读取迭代Map 是 iterable 的,可以直接被迭代(for...of)。for...in or keys遍历性能频繁增删键值对的场景下表现更好

    constructor 上的api

    Map Set WeakMap WeakSet 场景

    • 通过set 给Map对象新增键值。返回Map对象,可链式
    let myMap = new Map()
    let keyObj = {}
    myMap.set(keyObj, '新增键值')
    myMap.get(keyObj) // 新增键值
    myMap.get({}) // undefined
    myMap.get(NaN); // NaN 是一个
    // 注意是value key o
    myMap.forEach(function(value, key) {
      console.log(key + " = " + value);
    })
    

    Map与数组的关系

    二维数组的形式

    let arr = [[key, value], [xiaoming, 12]]
    let aMap = new Map(arr)
    let arr2 = [...aMap]
    console.log(Array.from(aMap.keys))
    // Map对象同数组进行合并时,如果有重复的键值,则后面的会覆盖前面的。
    let merged = new Map([...arr, ...xxx, [1, 'eins']]);
    
    

    通过map.set 进行值覆盖。

    注意!别为Map设置对象属性,而应该用set。不然会有意外。 let wrongMap = new Map() wrongMap['bla'] = 'blaa'

    3、WeakSet 只能是对象的集合,不能是任何类型的任意值、无法枚举

    WeakSet 对象集合中对象的引用为弱引用,不会被标记引用,容易被垃圾回收。

    递归、涉及较多对象时,使用。

    垃圾回收案例:

    let obj = {name : 'hhh'}
    // 如果新增 let array = [obj] 则不会被垃圾回收
    // let map = new WeakMap()  map.set(obj, '这样也是会被垃圾回收,因为是弱引用')
    obj = null // 可以被回收
    
    

    ECMAScript 6: what is WeakSet for?

    案例:

    案例1、我们可以将用户添加到 WeakSet 中,以追踪访问过我们网站的用户

    let visitedSet = new WeakSet();
    
    let john = { name: "John" };
    let pete = { name: "Pete" };
    let mary = { name: "Mary" };
    
    visitedSet.add(john); // John 访问了我们
    visitedSet.add(pete); // 然后是 Pete
    visitedSet.add(john); // John 再次访问
    
    // visitedSet 现在有两个用户了
    // 检查 John 是否来访过?
    alert(visitedSet.has(john)); // true
    // 检查 Mary 是否来访过?
    alert(visitedSet.has(mary)); // false
    john = null;
    // visitedSet 将被自动清理
    

    案例2、

    const requests = new WeakSet();
    class ApiRequest {
      constructor() {
        requests.add(this);
      }
      makeRequest() {
        if(!request.has(this)) throw new Error("Invalid access");
        // do work
      }
    }
    // 如果没有weakSet ,你可能需要 通过生命周期去管理,手动删除
    const requests = new Set();
    class ApiRequest {
      constructor() {
        requests.add(this);
      }
      makeRequest() {
        if(!request.has(this)) throw new Error("Invalid access");
        // do work
      }
      destory(){
        requests.delete(this)
      }
    }
    

    ApiRequest 类中想验证 this 对象的来源,于是需要一个集合来存所有通过构造函数构建的对象,ApiRequest 类却并不像参与到实例对象的生命周期中去,直接用 Set 的话,由于Set 对于实例对象存在引用,就会发生内存泄漏。

    案例3、DOM节点作为键名

    consturctor 上的api

    Map Set WeakMap WeakSet 场景

    4、WeakMap 键必须是对象、无法枚举

    WeakMap 对象是一组键/值对的集合,其中的键是弱引用的。其键必须是对象,而值可以是任意的。 Map 的赋值和搜索操作都是O(n)、且容易导致内存泄漏,因为数组会一直引用着每个键和值。

    基本上,如果你要往对象上添加数据,即额外数据的存储 又不想干扰垃圾回收机制,就可以使用 WeakMap。

    用来存这个对象相关的数据,与数据共存亡:

    • 案例1、一个用户对象作为键,其访问次数为值。当一个用户离开时(该用户对象将被垃圾回收机制回收),这时我们就不再需要他的访问次数了
    let visitsCountMap = new WeakMap()
    
    // 递归用户来访次数
    function countUser(user){
    	let count = visitsCountMap.get(user) || 0
        visitsCountMap.set(user, count + 1)
    }
    
    // ? main.js
    let john = { name: "John" };
    countUser(john); // count his visits
    // 不久之后,john 离开了
    john = null;
    
    • 案例2、缓存计算的结果
    let cache = new WeakMap()
    
    // 与obj 嘻嘻相关的结果
    function process(obj){
    	if(!cache.has(obj)) {
        	let result = `与obj有关的计算`
            cache.set(obj, result)
        }
        return cache.get(obj)
    }
    
    // other.js
    let obj = {}
    let result1 = process(obj)
    let result2 = process(obj)
    obj = null // 如果是Map 就cache 里不可被回收
    
    

    案例3、DOM节点作为键名

    consturctor 上的api

    Map Set WeakMap WeakSet 场景

    小汇:

    • Set 类似于数组,成员值唯一。
    • WeakSet 类似 Set,但成员只能是对象,且没有遍历操作。不引用后会被自动回收。
    • Map 类似于对象,key值不限于字符串,成员值唯一。
    • WeakMap 类似 Map,但只接受对象作为键名(null除外),且没有遍历操作。不引用后会被回收。

    MDN


    起源地下载网 » Map Set WeakMap WeakSet 场景

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元