useMap-管理map的钩子
map和Object的区别和相同
map"值"-"值"
1 .map {(1, “微笑”), (2, “哭泣”), (42, “快乐”)}
1 .map用于快速搜索和查找数据
2 .map中的key,value可以是任意数据类型
2 .map中的元素对的原始顺序是被包留的
3 .map是Object的实例
4 .map的键可以是任何类型.Date,Map,甚至自定义对象.但是如果搞很复杂的键,那查询岂不是也很麻烦,记不住吧
5 .为了快速搜索和查找数据而生的
6 .map是一个纯哈希机构,Object不是,他内部有自己的逻辑
7 .map的形式可以看成是"值"-"值"
Object"键"-"值"
1 .Object {1:'微笑',2:'哭',42:'快乐'}
2 .key必须是简单类型,整数,字符串,符号而已,symbol
3 .原始元素对顺序不保证.
4 .键的排序
1 .正整数,顺序是从小到大
2 .字符串,负整数,浮点数,顺序是插入顺序
3 .symbol,所有symbol根据插入顺序
5 .新增键是,可能覆盖原型上的键,Object都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突,更加意味着已经有一些内置的值了,增加复杂度
Object.prototype.x=1
const o={x:2}
const m=new Map([x,2])
o.x=2
//x=1将被覆盖
m.x=1
x=1不被覆盖
新建
1 .Object
let obj={}
let obj=new Object()
let obj=Object.create(null)
//内置构造函数性能更慢
2 .Map
let map=new Map()
//任何具有Iterator接口,每个成员都是一个双元素的数组的数据结构,都可以当作参数传进入,甚至set和map都可以用来生成新的Map
map.set('1',1).set('2',2)
//set返回新的set,所以支持链式调用
访问元素
1 .map.get(1) | Obj.id/Obj['id']
检查是否有某一项
1 .let isExist=obj.id===undefied | isExist='id' in obj
2 .map.has(1)
添加新元素
1 .obj:如果属性已存在,将会覆盖向原值
obj['a']='b'
obj.a=b
2 .map:如果是现有的key,将会用新值覆盖旧值
map.set('k','v')
const map = new Map();
const k1 = ['a'];
const k2 = ['a'];
map
.set(k1, 111)
.set(k2, 222);
map.get(k1) // 111
map.get(k2) // 222
//map的键实际上适合内存地址绑定的,只要内存地址不一样,就算是不同的,解决了同名属性碰撞的问题
3 .添加操作都是0(1)运行时间
移除/删除元素
1 .Obj没有专门的方法
delete obj.id
//将对象中完全删除特定属性
obj.id=undefined
//将改属性的值映射未undefined,属性还是保留在对象中,
//for ...in..遍历的时候还会遍历到这个属性
2 .map
1 .map.delete(id) :成功删除返回true,没有这个id的属性返回false,删除失败也会返回false
2 .map.clear()删除所有元素.Object想要这样做,需要遍历删除
3 .删除一个元素是O(1),删除全部是O(n),性能基本一样
获取大小
1 .map
map.size
2 .Object
Object.keys(obj).length
元素的迭代
1 .map:内置的可迭代对象,可以直接用for...of进行迭代.map全都是用这个迭代
//迭代方式1
for( const item of map){
console.log(item)
//里面就是单个的[key,value].之前也出现过类似的结构
}
//迭代方式2
for(const [key,value] of map){
console.log(key,value)
}
//迭代方式3,这个forEach方法和数组的不一样,是map专门的
map.forEach((e)=>{
console.log([key,value])
})
//迭代方式4
map.keys(),map.values(),map.entries()还是有效
2 .object:不是内置可迭代对象迭代方式是for in
//迭代方式1
for(let key in obj){
console.log(key,obj[key])
}
//迭代方式2
Object.keys(obj).forEach((e)=>{
console.log(key,obj[key])
})
使用Object的情况
1 .只需要简单的结构来存储数据并且知道所有键都是字符串和整数.少量结构的时候占用内存更小,新建非常高效
2 .需要键单独的逻辑应用于单个属性/元素的情况下,需要单独计算属性值obj.number++
const m = new Map([['x',1]]);
// 若想要将 x 的值在原有基础上加一,我们需要这么做:
m.set('x', m.get('x') + 1);
m.get('x'); // 2
const o = {x: 1};
// 在对象上修改则会简单许多:
o.x++;
o.x // 2
3 .需要数据序列化.JSON完全支持Object,不支持map.如果map想要序列化,还需要转换.大量使用json的时候,将object作为首选
4 .需要覆盖原型上的键时,用这个
5 .Object适用于复杂的对象,比如有函数方法
var obj = {
id: 1,
name: "It's Me!",
print: function(){
return `Object Id: ${this.id}, with Name: ${this.name}`;
}
}
console.log(obj.print());//Object Id: 1, with Name: It's Me.
使用map的时候
1 .map是纯哈希值,Object除了这个还有许多内部逻辑,很长的原型链,对Object使用delete有性能问题.需要大量删除和添加的数据,Map表现更好
2 .map保留了键的顺序,如果迭代或者元素顺序非常重要,使用map
3 .Map在存储大量数据的时候表现更好
4 .如果仅仅是需要键值对,那么map比Object更合适
性能对比
1 .创建.Object速度快于Map.空Obejct内存比map占用更少
2 .新增,map速度快于object.大量数据的时候map使用内存更少
3 .读取,Object略占优势,但是不大
4 .删除,map更快
1 .在Object里面,非负整数具有一定连续性时,会被当成快数组,过于稀疏被当成慢数组.快速组具有连续的内存,读写时会更快,占用更少的内存