胖蔡说技术
随便扯扯

Js中的Map和WeakMap的区别


Map

Map 中存储的是 key-value 形式的键值对, 其中的 key 和 value 可以是任何类型的, 即对象也可以作为 key . 这比用对象来模拟的方式就灵活了很多。

如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然NaN不严格相等于自身,但 Map 将其视为同一个键。

let map = new Map();

map.set(-0, 123);
map.get(+0) // 123

map.set(true, 1);
map.set('true', 2);
map.get(true) // 1

map.set(undefined, 3);
map.set(null, 4);
map.get(undefined) // 3

map.set(NaN, 123);
map.get(NaN) // 123

Map 的创建和初始化

1、可以用new Map()构造函数来创建一个空的 Map

// 创建一个空的 Map 
let map  = new Map()

2、也可以在 Map() 构造函数中传入一个数组来创建并初始化一个 Map. 传入的数组是二维数组, 其中的每一个子数组都有两个元素, 前面的元素作为 key, 后面的元素作为 value, 这样就形成了一个 key-value 键值对. 例如:

// 用数组来创建一个 非空的 Map 

let array = [ // 定义一个二维数组,  数组中的每子数组都有两个元素
    ['key1' ,  'value 1'],   // key 是 字符串 "key1", value 是字符串 "value 1"
    [{} ,  10086] ,          // key 是个对象, value 是数值 10086
    [ 5,  {} ]              // key 是个数值类型, value 是对象
];

let map = new Map(array);  // 将数组传入 Map 构造函数中

Map 的属性及方法

属性:

  • constructor:构造函数
  • size:返回字典中所包含的元素个数
const map = new Map([
  ['name', 'An'],
  ['des', 'JS']
]);

map.size // 2

操作方法:

  • set(key, value):向字典中添加新元素
  • get(key):通过键查找特定的数值并返回
  • has(key):判断字典中是否存在键ke
  • delete(key):通过键 key 从字典中移除对应的数据
  • clear():将这个字典中的所有元素删除

遍历方法

  • Keys():将字典中包含的所有键名以迭代器形式返回
  • values():将字典中包含的所有数值以迭代器形式返回
  • entries():返回所有成员的迭代器
  • forEach():遍历字典的所有成员

与其他数据结构的相互转换

  1. Map 转 Arrayconst map = new Map([[1, 1], [2, 2], [3, 3]]) console.log([…map]) // [[1, 1], [2, 2], [3, 3]]
  2. Array 转 Mapconst map = new Map([[1, 1], [2, 2], [3, 3]]) console.log(map)
  3. Map 转 Object因为 Object 的键名都为字符串,而Map 的键名为对象,所以转换的时候会把非字符串键名转换为字符串键名。function mapToObj(map) { let obj = Object.create(null) for (let [key, value] of map) { obj[key] = value } return obj } const map = new Map().set(‘name’, ‘An’).set(‘des’, ‘JS’) mapToObj(map) // {name: “An”, des: “JS”}
  4. Object 转 Mapfunction objToMap(obj) { let map = new Map() for (let key of Object.keys(obj)) { map.set(key, obj[key]) } return map } objToMap({‘name’: ‘An’, ‘des’: ‘JS’}) // Map {“name” => “An”, “des” => “JS”}
  5. Map 转 JSONfunction mapToJson(map) { return JSON.stringify([…map]) } let map = new Map().set(‘name’, ‘An’).set(‘des’, ‘JS’) mapToJson(map) // [[“name”,”An”],[“des”,”JS”]]
  6. JSON 转 Mapfunction jsonToStrMap(jsonStr) { return objToMap(JSON.parse(jsonStr)); } jsonToStrMap(‘{“name”: “An”, “des”: “JS”}’) // Map {“name” => “An”, “des” => “JS”}

WeakMap

WeakMap 对象是一组键值对的集合,其中的键是弱引用对象,而值可以是任意。

注意,WeakMap 弱引用的只是键名,而不是键值。键值依然是正常引用。

WeakMap 中,每个键对自己所引用对象的引用都是弱引用,在没有其他引用和该键引用同一对象,这个对象将会被垃圾回收(相应的key则变成无效的),所以,WeakMap 的 key 是不可枚举的。

属性:

  • constructor:构造函数

方法:

  • has(key):判断是否有 key 关联对象
  • get(key):返回key关联对象(没有则则返回 undefined)
  • set(key):设置一组key关联对象
  • delete(key):移除 key 的关联对象
let myElement = document.getElementById('logo');
let myWeakmap = new WeakMap();
myWeakmap.set(myElement, {timesClicked: 0});
myElement.addEventListener('click', function() {
  let logoData = myWeakmap.get(myElement);
  logoData.timesClicked++;
}, false)
  • Map

本质上是键值对的集合,类似集合 可以遍历,方法很多可以跟各种数据格式转换

  • WeakMap

只接受对象作为键名(null除外),不接受其他类型的值作为键名 键名是弱引用,键值可以是任意的,键名所指向的对象可以被垃圾回收,此时键名是无效的不能遍历,方法有get、set、has、delete.

赞(2) 打赏
转载请附上原文出处链接:胖蔡说技术 » Js中的Map和WeakMap的区别
分享到: 更多 (0)

请小编喝杯咖啡~

支付宝扫一扫打赏

微信扫一扫打赏