当前位置: 首页 > news >正文

【JavaScript】JS——Map数据类型

【JavaScript】JS——Map数据类型

什么是Map?

存储键值对的对象。


  1. 能够记住键的原始插入顺序
  2. 任何值(对象或原始值)都可以作为键或值。

特性

Map中的一个键只能出现一次,新的值会覆盖旧的值。

迭代方式:for…of循环,返回一个 [key,value] 的数组。

键的相等:基于零值相等比较

NaN === NaN
-0 === +0

Map与Object的比较

  • Map默认不包含任何键。它只包含显示存入的键值对。object 有原型
let map1 = new Map()
let obj1 = new Object()console.log(map1);
console.log(obj1);

在这里插入图片描述

  • 安全性:Map是一种独立的数据结构,不存在对象原型。而在 Object上设置用户提供的键值对可能会允许攻击者覆盖对象的原型,这可能会引发潜在的安全问题:

    • 原型链污染:攻击者通过提供特定的键值对,污染对象的原型链。例如,攻击者可以通过设置 __proto__ 属性来修改对象的原型,从而修改或劫持对象的原型上的方法和属性。
    • 函数劫持:如果用户提供的键值对中的值是一个函数,并且该函数被直接赋值给对象的属性,攻击者可能会通过提供恶意的函数来劫持对象的属性。
    • 对象重写:如果用户提供的键值对中的键与对象的原型中的属性冲突,攻击者可能通过提供特定的键值对来覆盖对象的原型属性。
    • 访问限制绕过
    const victim = {};
    const attacker = { evilMethod: () => console.log('恶意方法被调用') };victim.__proto__ = attacker;// 调用原型上的恶意方法
    victim.evilMethod(); // 恶意方法被调用
    
  • 键的类型:Map的键可以为任何值(函数、对象或任何原始值),Object 的键必须为 StringSymbol

    • 键为函数实例:缓存函数调用结果

      const cache = new Map();function createCacheKey(fn, ...args) {return `${fn.name}(${args.join(',')})`;
      }function calculateResult(x, y) {const cacheKey = createCacheKey(calculateResult, x,  y);if (cache.has(cacheKey)) {console.log('从缓存中获取结果');return cache.get(cacheKey);
      }const result = x + y;cache.set(cacheKey, result);return result;
      }console.log(calculateResult(2, 3)); // 输出:5
      console.log(calculateResult(2, 3)); // 输出:从缓存中获取结果,5
      
  • 键的顺序:Map 对象按照插入的顺序迭代条目、键和值。

  • 大小:Map中的项目数量,使用 size属性获知,Object通常是通过获取 Object.keys()返回的数组长度。

  • 迭代:Map 是可迭代对象,Object没有实现迭代协议,默认不能通过 for ...of实现迭代

  • 性能:涉及频繁添加和删除键值对的场景表现更好

  • 序列化或解析:Map 没有序列化或解析的原生支持;Object支持使用 JSON。stringify()序列化Object到JSON,使用 JSON.parse()解析JSON为Object

map的创建

  • 语法
new Map()
new Map(iterable)

iterable 一个元素是键值对的数组或其他可迭代对象。

const map1 = new Map()
const map2 = new Map([[1, "a"],[2, "b"],[3, "c"],[4, "c"]
])console.log(map1,map2);

在这里插入图片描述

map的属性

size()

map2.size // 4

map相关方法

get()

get(key) 获取该 map 中的指定元素

console.log(map2.get(1)); // a

set()

set(key, value)Map 对象添加或更新一个指定的键值对

map1.set("a", 1)
map1.set("a", 3)
map1.set("b", 2)// 链式添加 键值对
map1.set("bar","foo").set(1, "foobar")
console.log(map1);

在这里插入图片描述

has()

返回一个布尔值,指示具有指定键的元素是否存在.

delete()

delete(key)从该 map 中删除指定键的元素。

console.log(map1.delete("a"));	// true 删除成功返回true

clear()

移除该 map 中的所有元素.

map1.clear()
console.log(map1); // Map(0) {size: 0}

groupBy()

Map.groupBy(items, callbackFn)

Map对象每个元素都执行提供的回调函数,根据回调函数返回的值进行分组

const inventory = [{ name: 'Tom', age: 9 },{ name: 'Bob', age: 5 },{ name: 'Alice', age: 23 },{ name: 'Taixi', age: 12 },
];const result = Map.groupBy(inventory, ({ age }) =>
age < 18 ? "teenager" : "young",
);
console.log(result.get("teenager"));

在这里插入图片描述

map的遍历

forEach()

forEach(callbackFn) 按插入顺序对该 map 中的每个键/值对执行一次提供的函数。

const map2 = new Map([[1, "a"],[2, "b"],[3, "c"],[4, "c"]
])function logMapElement(value, key, map) {console.log(`m[${key}]=${value}=${map.get(key)}`);
}map2.forEach(logMapElement)

entries()

按照插入顺序,返回一个新的可迭代迭代器对象,包含了Map对象中的所有键值对。

const mapIter = map2.entries()console.log(mapIter.next().value);
console.log(mapIter.next().value);
console.log(mapIter.next().value);

在这里插入图片描述

keys() | values()

返回一个迭代器对象,keys()方法返回Map对象中每个元素的键,values()方法返回Map对象中每个元素的值。

const mapIter1 = map2.keys()console.log(mapIter1.next().value);
console.log(mapIter1.next().value);
console.log(mapIter1.next().value);const mapIter2 = map2.values()console.log(mapIter2.next().value);
console.log(mapIter2.next().value);
console.log(mapIter2.next().value);

在这里插入图片描述

http://www.lryc.cn/news/254738.html

相关文章:

  • 【【FPGA的 MicroBlaze 的 介绍与使用 】】
  • PyQt pdf格式保存
  • 微前端介绍
  • 工业机器视觉megauging(向光有光)使用说明书(一,轻量级的visionpro)
  • Java——面试:String 和 StringBuffer 的区别?
  • 图扑软件受邀出席高交会-全球清洁能源创新博览会
  • vue项目下npm或yarn下安装echarts多个版本
  • 在内网开发中使用Nginx代理来访问钉钉新版服务端API
  • 机器学习算法如何进行特征重要性评估
  • 运行启动vue项目报报错node: --openssl-legacy-provider is not allowed in NODE_OPTIONS解决
  • 网工学习5 交换机端口相关配置
  • 使用Pytorch从零开始实现CLIP
  • Java网络编程 *TCP与UDP协议*
  • 校园外卖小程序源码系统 附带完整的搭建教程
  • TiDB专题---1、TiDB简介和特性
  • 如何二次封装一个Vue3组件库?
  • 2024年网络安全比赛--系统渗透测试(超详细)
  • 高效的单行python脚本
  • 如何通过内网穿透实现无公网IP也能远程访问内网的宝塔面板
  • 【广州华锐互动】VR沉浸式体验铝厂安全事故让伤害教育更加深刻
  • CFLAGS、CXXFLAGS、FFLAGS、FCFLAGS、LDFLAGS、LD_LIBRARY_PATH区别
  • 阿里云租赁费用_阿里云服务器多配置报价表
  • 网络层(1)——概述
  • 计算机网络——网络层
  • Antd search input无中框
  • 【PyTorch】概述
  • 非对象集合交、并、差处理
  • 时间序列预测实战(二十五)PyTorch实现Seq2Seq进行多元和单元预测(附代码+数据集+完整解析)
  • 电子学会C/C++编程等级考试2022年09月(三级)真题解析
  • 【数据库】基于时间戳的并发访问控制,乐观模式,时间戳替代形式及存在的问题,与封锁模式的对比