Javascript Map与WeakMap

作为ES6新增特性,Map是一种新的集合类型,与Object一样,它也是键值对的集合,但是两者还是存在差别的

  1. Map基本API

创建map

const m = new Map()

set:添加键值对

const m = new Map()
m.set('name', 'khkkm')
console.log(m) //{ 'name' => 'khkkm' }
m.set('name', 'khkkn')
console.log(m) //{ 'name' => 'khkkn' }
m.set('age', 20).set('sex', '男')
console.log(m) //{ 'name' => 'khkkn', 'age' => 20, 'sex' => '男' }

使用set添加的新成员,键如果已经存在,后添加的键值会覆盖已有的键值。set方法,返回Map实例,因为可以串联多个操作。

get:通过键获取值

console.log(m.get('age'),m.get('grade')) //20 undefined

获取不存在的成员,返回undefined

has:判断是否有某个成员

console.log(m.has('age'),m.has('grade')) //true false

delete:删除

m.delete('sex')
console.log(m) //{ 'name' => 'khkkn', 'age' => 20 }
m.delete('grade')
console.log(m) //{ 'name' => 'khkkn', 'age' => 20 }

删除不存在的键,什么都不会发生

clear:清空

m.clear()
console.log(m) //{}

size:获取有几个键值对(属性)

console.log(m.size) //0
  1. Map特点

Object只能使用数值、字符串或符号作为键,而Map可以使用任何Js数据类型作键

const m = new Map()
m.set('name', 'khkkm')
m.set(true, 'true')
m.set({}, 'object')
m.set(new Set([1, 2]), 'set')
m.set(undefined, 'undefined')
console.log(m) 

{
  'name' => 'khkkm',
  true => 'true',
  {} => 'object',
  Set(2) { 1, 2 } => 'set',
  undefined => 'undefined'
}

Map内部的判等方式基本上相当于使用严格相等(===),除了NaN,Map中的NaN等于NaN

const m = new Map()
const a = parseInt('a')
const b = parseFloat('b')
console.log(a, b, a === b)
m.set(a, '我是a的值')
m.set(b, '我是b的值')
console.log(m.get(a))
//NaN NaN false 我是b的值

与Object另一个差异,Map实例会维护键值对的插入顺序

const m = new Map()
m.set(1, 1)
m.set(4, 4)
m.set(3, 3)
m.set(2, 2)
console.log(m) //{ 1 => 1, 4 => 4, 3 => 3, 2 => 2 }
const obj = {}
obj[1] = 1
obj[4] = 4
obj[3] = 3
obj[2] = 2
console.log(obj) //{ '1': 1, '2': 2, '3': 3, '4': 4 }

Map迭代

//创建的同时初始化,可以给Map传入一个二维数组,但是必须要体现出键和值
const m = new Map([
  ['name', 'khkkm'],
  ['age', 18]
])
for (pairs of m) {
  console.log(pairs)
}
[ 'name', 'khkkm' ]
[ 'age', 18 ]
//单独获取键
for (key of m.keys()) {
  console.log(key)
}
name
age
//单独获取值
for (value of m.values()) {
  console.log(value)
}
khkkm
18
//m.forEach(function(value,key,map){},this指向)  value:值,key:键,map:m本身
m.forEach((val, key, map) => {
  console.log(key + '=>' + val, map)
})
name=>khkkm Map(2) { 'name' => 'khkkm', 'age' => 18 }
age=>18 Map(2) { 'name' => 'khkkm', 'age' => 18 }

什么时候使用Map?

如果只是需要key->value的结构,或者需要数值、字符串或符号以外的值做键,使用Map更合适

  1. 强引用与弱引用

强引用:对象的引用在 JavaScript 中是强引用,也就是将个引用对象通过变量或常量保存时,那么这个变量或常量就是强引用,这个对象就不会被回收。

弱引用:WeakMap和 WeakSet是在 JavaScript 使用弱引用唯一途径,将一个对象作为键添加 WeakMap 或 WeakSet 中并不能防止这些对象被回收。

水平有限,代码例子举不出来。。。所以上图

变量1、变量2、Map都有着对某个Object实例对象的强引用,随着一个一个的被释放,最终某个Object实例对象失去了所有对它的强引用,然后它被垃圾回收了。

变量1、变量2、WeakMap都有着对某个Object实例对象的引用,随着强引用们被释放,最终某个Object实例对象失去了所有对它的强引用,然后它被垃圾回收了。

  1. WeakMap

ES6新增“弱映射”,也是一种新的集合类型,weak描述的是垃圾回收程序对待“弱映射”中键的方式(即弱引用)

WeakMap基本API

const m = new WeakMap()
const user1 = { name: '张三', age: 20 }
const user2 = { name: '李四', age: 17 }
const user3 = { name: '王五', age: 21 }
m.set(user1, 'user11')
m.set(user2, 'user22').set(user3, 'user33')
console.log(m.get(user1)) //user11
console.log(m.has(user2)) //true
m.delete(user2)
console.log(m.has(user2)) //false

区别于Map,WeakMap的基本API仅有如上,它没有clear和size

WeakMap特点

1 WeakMap的键只能是Object或者继承自Object的类型,如上述代码所示,值的类型无限制。

2 “weak”,表示这些键不属于正式的引用,不会阻止垃圾回收。

3 不可迭代,因为弱映射中的键值对可能随时被销毁,所以没必要提供迭代的能力,也不用像clear一次性清空所有,所以也没有clear方法。

什么时候使用WeakMap?

由于WeakMap不会妨碍垃圾回收,所以它很适合应用于某元素用完就应该立即被释放的场景。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值