JavaScript中如何正确删除Map内键为数组的条目
删除失败的核心原因
JavaScript的Map对键的匹配采用SameValueZero相等判定规则,和严格相等===的逻辑一致:
- 原始类型(字符串、数字、布尔值等)比较值是否相等
- 数组、对象这类引用类型,比较的是内存引用地址,而非实际存储的内容
你初始化Map时写的[ 10, 10, 9 ]和调用delete()时传入的[10, 10, 9]是两个独立创建的数组实例,在内存里是完全不同的地址,Map会判定二者不是同一个键,自然无法匹配到要删除的条目。
你可以用这段代码验证引用比较的逻辑:
console.log([10,10,9] === [10,10,9]) // 输出false
可行的实现方案
你可以根据自己的业务场景选下面任意一种方式实现:
- 提前保存数组键的引用
初始化Map时就把作为键的数组存到单独的变量里,后续增删改查都复用这个变量,保证引用一致:// 提前定义键,固定引用 const qualityControlKey = [10, 10, 9] const coffee = new Map([ ['Roast', 'Dark'], ['Origin', 'Chiapas'], [304029198, 'Batch serial number'], ['Packed Date', 20220134], [1045, 'River One Store'], [qualityControlKey, 'Quality Control'], [true, 'Packed'], [false, 'Not packed'] ]) // 直接传入保存的引用即可成功删除 coffee.delete(qualityControlKey) - 遍历匹配键内容后删除
如果初始化时没有保存键的引用,可以遍历Map的所有键,找到内容完全匹配的数组键后再执行删除:const targetKey = [10, 10, 9] for (const key of coffee.keys()) { // 先判断是否为数组,再逐位比较元素是否匹配 if ( Array.isArray(key) && key.length === targetKey.length && key.every((item, index) => item === targetKey[index]) ) { coffee.delete(key) break } } - 序列化数组为原始类型做键
如果数组元素都是基本类型、元素顺序固定,可以在存值时把数组序列化为字符串这类原始类型作为键,从根源上避免引用比较的问题:// 存值时把数组转成逗号分隔的字符串 coffee.set([10,10,9].join(','), 'Quality Control') // 删除时也做相同格式的转换 coffee.delete([10,10,9].join(','))
内容的提问来源于stack exchange,提问作者eduairet
相关产品推荐
相关产品推荐

