JavaScript红宝书学习4——集合引用类型2)定型数组,Map,Set

《JavaScript红宝书(第四版)》第6章

6.3 定型数组

目前项目中没有对其进行应用,暂且跳过细节

6.4 Map

6.4.1 基本API
//注意初始化,new Map()后的[]是双层数组,否则报错
let map1 = new Map([['zhangsan', 23],['lisi',34]]) 
map1.set('wangwu', 28) //Map(3) {"zhangsan" => 23, "lisi" => 34, "wangwu" => 28} 
map1.has('lisi') //true 
map1.has('lili') //false 
map1.get('wangwu') //28 
map1.delete("lisi") //true 
map1 //Map(2) {"zhangsan" => 23, "wangwu" => 28} 
map1.clear() //undefined 
map1 //Map(0) {}

Map与Object不同,Object的key只能是数值、字符串或者符号。Map的key可以是任意类型,如function, object, Symbol

6.4.2 顺序与迭代

与Object不同,Map会维护键值对插入的顺序,可以根据该顺序进行迭代操作

  • 使用entries或者Symbol.iterator迭代:
let map1 = new Map([['zhangsan', 23],['lisi',34]])

for(let pair of map1.entries()){
console.log(pair)
}
//(2) ["zhangsan", 23]
//(2) ["lisi", 34]

for(let pair of map1[Symbol.iterator]()){
console.log(pair)
}
//(2) ["zhangsan", 23]
//(2) ["lisi", 34]
  • 使用forEach, 这样语句更简洁
map1.forEach((key, val) => console.log(`key: ${key}, value: ${val}`))
//key: 23, value: zhangsan
//key: 34, value: lisi

map1.forEach(val => console.log(val))
//23
//34
  • 使用解构直接转换为Array
const arr2 = [...map1]
arr2
//(2) ["zhangsan", 23]
//(2) ["lisi", 34]
  • 访问xxx.keys(), xxx.values()同样生效,与Object类似

  • 迭代中,修改key值后,key的引用不会被修改,该场景暂时未遇到。

6.4.3 Object VS. Map
对比项目胜出者
内存占用Map
插入速度Map略胜一筹
查找速度差异极小,大量查找偏向于Object
删除性能Map胜出,由于Object删除后会继续留下该key,将value改为null或undefined而饱受诟病

6.5 WeakMap(了解,尚未深入研究)

  1. WeakMap相比于Map的一些特性

    • key只能是Object,value无限制
    • 不能遍历key
    • 只有get, set, has, delete方法,没有keys, values, entries, 没有size属性,没有clear方法
  2. 使用场景

    MDN: 如果你想要往对象上添加数据,而又不想干扰垃圾回收机制,可以使用WeakMap

    比如DOM节点元数据,数据缓存,私有变量等

6.6 Set

  • 基础API

    【注意】, Set的key与value相同

const s = new Set()
s.add('pink').add('yellow') //Set(2) {"pink", "yellow"}
s.has('pink') //true
s.has('purple') //false

//keys与values,得到的结果相同
const arr = s.keys()
const arr1 = s.values()
arr //SetIterator {"pink", "yellow"}
arr1 //SetIterator {"pink", "yellow"}

//set中的元素,可以添加任何类型
let func = function() {}
s.add(func) //Set(3) {"pink", "yellow", ƒ}

//重复添加,是不起作用的,自动去重
s.add('pink') //Set(3) {"pink", "yellow", ƒ}

//delete操作,返回布尔值
s.delete('yellow') //true
s.delete('black') //false
  • 顺序与迭代

    与Map特性相同,Set也会维护插入的顺序,可以根据该顺序进行迭代操作

    • 迭代的方式,与Map类似, keys, values, entries, forEach
    • 由于key与value相同,所以使用entries进行迭代时,得到的是[value, value]这样的结构

6.7 正式集合操作

可以定义多个集合的并集,交集,差集等操作,如果对于array也有类似的需求,可以先转换为Set再进行操作,也很方便快捷,这里复制代码,以后作为工具类使用即可

class XSet extends Set {
	union(...sets) {
	  return XSet.union(this, ...sets)
	}
	intersection(...sets) {
	  return XSet.intersection(this, ...sets)
	}
	difference(set) {
	  return XSet.difference(this, set)
	}
	symmetricDifference(set) {
	  return XSet.symmetricDifference(this, set)
	}
	cartesianProduct(set) {
	  return XSet.cartesianProduct(this, set)
	}
	powerSet() {
	  return XSet.powerSet(this)
	}

	// 返回两个或更多集合的并集
	static union(a, ...bSets) {
	  const unionSet = new XSet(a)
	  for (const b of bSets) {
		for (const bValue of b) {
		  unionSet.add(bValue)
		}
	  }
	  return unionSet
	}
	// 返回两个或更多集合的交集
	static intersection(a, ...bSets) {
	  const intersectionSet = new XSet(a)
	  for (const aValue of intersectionSet) {
		for (const b of bSets) {
		  if (!b.has(aValue)) {
			intersectionSet.delete(aValue)
		  }
		}
	  }
	  return intersectionSet
	}
	// 返回两个集合的差集
	static difference(a, b) {
	  const differenceSet = new XSet(a)
	  for (const bValue of b) {
		if (a.has(bValue)) {
		  differenceSet.delete(bValue)
		}
	  }
	  return differenceSet
	}
	// 返回两个集合的对称差集
	static symmetricDifference(a, b) {
	  // 按照定义,对称差集可以表达为
	  return a.union(b).difference(a.intersection(b))
	}
	// 返回两个集合(数组对形式)的笛卡儿积
	// 必须返回数组集合,因为笛卡儿积可能包含相同值的对
	static cartesianProduct(a, b) {
	  const cartesianProductSet = new XSet()
	  for (const aValue of a) {
		for (const bValue of b) {
		  cartesianProductSet.add([aValue, bValue])
		}
	  }
	  return cartesianProductSet
	}
	// 返回一个集合的幂集
	static powerSet(a) {
	  const powerSet = new XSet().add(new XSet())
	  for (const aValue of a) {
		for (const set of new XSet(powerSet)) {
		  powerSet.add(new XSet(set).add(aValue))
		}
	  }
	  return powerSet
	}
}

6.8 WeakSet

类似于WeakMap,它的作用也是偏重于垃圾回收机制,在vue的源码中应该有所使用,尤其是在进行DOM节点打标签时,如果元素从DOM树中删除了,那么WeakSet就会回收元素的内层,而Set则不会。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值