理解ES6--第6部分:set 和 map , js中的字典,地图,弱字典和弱地图

本文介绍了ES6中的Set和Map数据结构,以及它们与ES5的对比。Set自动去重,不强制转换键值为字符串。Map允许任意类型键值对。此外,还讲解了WeakSet和WeakMap,它们用于优化内存管理,键必须为对象,且不支持遍历,旨在解决内存泄露问题。
摘要由CSDN通过智能技术生成

英文电子书点此阅读《understanding es6》

目录

set and map 字典和地图

ES5中模拟set和map
let set = Object.create(null)

//set 用于检查某个值是否存在。map用于缓存某个值。
  • 在对象内部, key值会被转化成字符型的。o[5] === o[‘5’]
 let map = Object.create(null),
    key1 = {},
    key2 = {};

map[key1] = "foo";

console.log(map[key2]);     // "foo"
  • 对象类型的转成字符都是’[object Object]’,因此key1 和 key2 都指向同一个值。
ES6中的set
  • set会自动去重。用set.add()添加项目。添加进去的不会被转换为字符类型。
  • set 没有key
let set = new Set();
set.add(5);
set.add("5");
set.add(5);

console.log( set.size )    // 2
  • set 构造器接收任意的 iterable 对象 作为参数。如 array, set 和 map。
  • 用 set.has() 方法来判断是否存在这一项目。
set.delete(5)  // 从set中删除某元素

set.clear()  // 清空set
  • set.forEach() 中接收一个回调函数作为第一个参数,该回调接收3个参数。
  • 第一个参数和第二个参数是一样的,都是下一个位置的元素,第三个参数是该set本身
  • 相当于 value , key , ownerSet,但 value 和 key 相等。
  • set.forEach() 的第二个参数是this, 如果要在回调中用到this, 通过第二个参数把 this 传进去。
  • 可以通过用 箭头函数 来避免 this 绑定的问题

  • 把 set 转换成 array

function eliminateDuplicates(items){
    return [...new Set(items)]  
}
  • set 可以被看做 strong set, 这是因为存在set中的对象引用与存在变量中的引用是一样的(有点绕)。也就是说,只要该set存在,这个对象就不能被内存回收。某些时刻,当不想要维持这么多对象的时候(比如一个被完全移除掉的dom树),为了避免内存泄露,需要在set中清除掉这些对象。
let key = {}, set = new Set{}
set.add(key)
key = null

set.size  //1
[...set][0] // {}

key = [...set][0]   // 恢复了key的值
  • ES6 引入了 weakSet 类型。 weakSet 只允许添加 weak object reference,不能储存基本类型的值。当一个对象的引用只在这个 weak map中存在时,它就会被回收掉。
  • WeakSet 与 Set 的区别包括:

    1. WeakSet的add()不接受非对象的值,而 has()/delete() 会对 非对象的参数 返回 false
    2. 弱字典 不能遍历,不能用 for-of, 也没有 forEach 方法
    3. 弱字典 不暴露任何的 Iterator, 因此无法从程序上判断一个 weakSet 的内容
    4. 弱字典没有 clear 方法。
    5. 弱字典没有 size 属性。
ES6中的地图 map
  • map 中的 key 可以是任意类型,而且与Set一样,都不会像 object 一样,被强制转换成 字符串类型。
let map = new Map();
map.set("title", "Understanding ES6");

let key1 = {}
map.set(key1,23)

map.get('title')   // "Understanding ES6"
map.get({})  // undefined
map.get(key1) //23
  • has(key), delete(key), clear(key) 是map 和 set 公有的方法。

  • 初始化 map 可以用一个二维数组,类似[ [key1,value1],[key2,value2]… ] 把keys存在数组可以保证它们不被强制转成其他类型的值。

let map = new Map([["name", "Nicholas"], ["age", 25]]);
map.forEach(function(value, key, ownerMap) {
    console.log(key + " " + value);
    console.log(ownerMap === map);
});

/*
name Nicholas
true
age 25
true
*/
  • weakMaps 弱地图 类似于 WeakSet,也是为了解决内存泄露问题而存在。
let map = new WeakMap(),
    element = document.querySelector(".element");

map.set(element, "Original");

let value = map.get(element);
console.log(value);             // "Original"

// remove the element
element.parentNode.removeChild(element);
element = null;

// the weak map is empty at this point
  • 也是用二维数组来初始化weakmap,但注意,key必须为一个对象
  • weakmap 只有 has(), get(),set(), delete()方法。

  • 可以用 weakMap 来存储对象的私有属性。

  • 还可以用 WeakMap 来存储对象的私有属性

  • ES5是这么完成的 这段代码写得很妙啊~
var Person = (function(){

    var privateData = {}, privateId = 0 

    function Person(name){

        Object.defineProperty(this,"_id", {value: privateId++ })

        privateData[this._id] = {

            name: name
        }
    }

    Person.prototype.getName = function(){

        return privateData[this._id].name
    }

    return Person   

}())

// 这么做的问题在于,privateData中存储的数据不会被清除掉,因为不知道什么对象的实例何时被摧毁了,privateData对象总会包含多余的数据。
  • WeakMap 能解决这个问题
let Person = (function(){

    let privateData = new WeakMap()

    function Person(name){
        privateData.set(this, {name:name} ) // Person作为对象本身就可以用来当key,所以就不用单独开 id 了。而且当实例被销毁的时候,privateData里面的数据也被销毁了
    }

    Person.prototype.getName = function(){
        return privateData.get(this).name
    }
})
  • 如果你只想用object类型的作Key, 那 weakmap 是最好的选择,但其内容难于枚举和看到。
summary
  • Sets are ordered lists of unique values. key即value,自动去重,不强制key/value被转为字符串类型。
  • weakset 是只含有对象的 特殊set。 对管理内存进行了优化。但难于检查其内容,所以最好在管理联结在一起的一组对象时用。
  • Maps are ordered key-value pairs where the key can be any data type. 不强制转换类型。
  • weakMap 只含有 对象类型的key 。也对垃圾回收进行了优化。特别适用于管理 生命周期在获取其值的代码之外的 对象。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值