类型“unknown”上不存在属性“foreach”_JavaScript红宝书第四版精简解析系列--映射Map数据类型...

fdbdfff47ad3d1ea495b640ca99e7031.png

Map数据类型

顾名思义

也就是映射类型,包含一个[[Entries]]私有特性

我们可以使用一个二维数组作为初始值

 const map1 = new Map([
        [1, 1],
        [2, 2],
        [3, 3],
 ]);
console.log("Map数据类型====>", map1);

当然也可以使用迭代器进行初始化

const map2 = new Map({
     [Symbol.iterator]: function* () {
        yield* [
          [1, 1],
          [2, 2],
          [3, 3],
        ];
      },
   });
 console.log("Map数据类型====>", map2);

我们来看一下Map数据类型内部结构(着重看下私有特性)

550d6feaa40ddd1ad7276f255dc47766.png

我们可以看到,Map数据类型包含了一个[[Entries]]私有特性

这个特性中可以看到一个清晰的映射关系

而在Map数据类型的原型上还挂在了很多方法

诸如 get set delete clear等操作方法

还有一个关于size属性的get访问器特性

另外,我们还可以清晰地看到

Map数据类型包含着迭代器属性,且迭代方法默认为entries()

我们首先来学习一下关于Map的操作方法


.set()
  const emptyMap = new Map();
  console.log("emptyMap====>", emptyMap);
  emptyMap.set('name', 'shang')
  console.log("set结果====>", emptyMap);

4256d141733762ee79139b6867c6e1bf.png
新增映射关系

由于set方法会返回被操作的Map数据,所以可以链式调用

 emptyMap.set("gender", "male").set("age", 17);
 console.log("set结果====>", emptyMap);

b4fe27cc6108a53ca012e155bd52398f.png
可以链式调用
.get()
console.log('get方法====>', emptyMap.get('name')

ee35ade2324f1a8edb791dd8d926e3f1.png
通过键获取映射值
.has()
 console.log('has方法====>', emptyMap.has('name'))

7bbe8d8186b5019100e2a1962c2905fe.png
通过has方法检验映射是否存在
.delete()
emptyMap.delete('name')
console.log("delete结果====>", emptyMap);

9ebd2e8486c33f2202c77ee2b57278be.png
使用delete删除一个映射
.clear()
 emptyMap.clear()
 console.log("emptyMap的size====>", emptyMap.size);

6158cf8b693530832e48ad81375920b2.png
clear后,所有映射关系都被清除了

Map数据类型可以接受各种类型的作为键

这里我们测试一下,function, Symbol 以及Object类型

 const functionKey = function() {};
 const symbolKey = Symbol()
 const objectKey = new Object()

 emptyMap.set(functionKey, functionKey).set(symbolKey, symbolKey).set(objectKey, objectKey)
 console.log('各种特殊键值对===>', emptyMap)

77a52bb02f0d00918e65cdf1b7de3e41.png

复杂类型作为键值时,Map类型并不保存快照,而是保存指针

这句话听起来挺唬人

but其实理解起来很简单

我举个例子

const emptyArr = [];
const emptyObj = {};
emptyMap.set(emptyArr, emptyObj);
emptyArr.push("1");
emptyObj.name = "shang";
console.log("复杂类型特殊键值对===>", emptyMap);
console.log("复杂类型特殊值===>", emptyMap.get(emptyArr));

8d437d3906f0d4e2bbd4cfb33c11023a.png

顺序维护和迭代方法

Map会自动维护关于元素的顺序

而且从上面Map数据类型原型链我们可以得知

Map数据类型包含一个默认方法为entries的迭代器

console.log('Map数据类型默认迭代器', 
   emptyMap.entries === emptyMap[Symbol.iterator])

946aa4c657c80d862b7d8db46e58b2f4.png
forof
for (const [key, value] of emptyMap) {
     console.log("forof映射元素分别为===>", key, value);
}

64b1b2195aac988a8be236f758633798.png
Map可以使用forof方法展开迭代
拓展运算符
console.log("拓展运算符用于Map数据类型", [...emptyMap]);

b65ae6a044dd0bd397611d384b514716.png
拓展运算符与forof公用迭代器
forEach方法
emptyMap.forEach((value, key) => {
        console.log("forEach映射元素分别为===>", key, value);
});

a3fa57cb07837df326b348e2df2a0e09.png

Map关于forEach的迭代效果与数组类似,value在前,key在后


Map使用values & keys 返回映射的迭代器

keys返回映射关于key的迭代器
可以用于forof 拓展运算符 Map Set等等
// Map使用values & keys 返回映射的迭代器
const keysIterator = emptyMap.keys();
console.log("Map的keys的迭代器===>", keysIterator);
for (const iterator of keysIterator) {
     console.log("keysIterator===>", iterator);
}

da1a6d55659131b762ea4d97e598eacc.png
values返回映射关于value的迭代器
可以用于forof 拓展运算符 Map Set等等
const valuesIterator = emptyMap.values();
console.log("Map的values的迭代器===>", valuesIterator);
for (const iterator of valuesIterator) {
     console.log("valuesIterator===>", iterator);
}

8cca4c9a36861be22eb4d23da8c88951.png

Map相较于Object有何优缺点???

数据类型占用内存插入数据删除数据查数据
Map同等数据量比Object少占50%内存插入更快,更省性能删除更快,更省性能×
Object×××有线性优化,查找更快,数据量越大查找优势越明显
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值