双元素数组为Map键的访问问题:原因解析与便捷方案
Map引用类型键的访问问题解析
为什么直接用新数组访问会失败?
这和原型无关,核心原因是数组是引用类型。Map判断键是否相等用的是SameValueZero算法:对于引用类型,只有当两个值指向同一个内存地址时,才会被判定为相等。
你创建Map时用的[[3,6], 'hello']里的数组,和调用myMap.get([3,6])时的新数组,是两个完全独立的对象,内存地址不同,所以Map找不到对应的键,返回undefined。而keyArray[0]是直接取出了Map里存储的原数组引用,地址和创建时的键完全一致,所以能匹配到值。
如何便捷且动态地访问这类键?
1. 保存原键的引用
如果能在创建Map时就把键数组存为变量,后续直接用这个变量访问是最高效的方式:
const myKey = [3, 6]; const myMap = new Map([[myKey, 'hello']]); console.log(myMap.get(myKey)); // 输出 'hello'
2. 遍历Map匹配数组内容
如果没办法保存原引用,可以遍历Map的键值对,手动比较数组的内容:
// 通用数组比较函数 function arraysEqual(a, b) { if (a.length !== b.length) return false; for (let i = 0; i < a.length; i++) { if (a[i] !== b[i]) return false; } return true; } // 根据数组内容查找Map值 function getMapValueByArrayKey(map, targetKey) { for (const [key, value] of map) { if (arraysEqual(key, targetKey)) { return value; } } return undefined; } // 使用示例 const myMap = new Map([[[3,6], 'hello']]); console.log(getMapValueByArrayKey(myMap, [3,6])); // 输出 'hello'
3. 将数组转为基本类型作为键
把数组转换成字符串、数字等基本类型当键,利用基本类型按值比较的特性。常用的方式是JSON.stringify:
const myMap = new Map([[JSON.stringify([3,6]), 'hello']]); console.log(myMap.get(JSON.stringify([3,6]))); // 输出 'hello'
注意:这种方式只适合数组元素能被JSON序列化的场景(比如不包含函数、Symbol、循环引用等),否则会导致序列化结果不一致,无法匹配。
内容的提问来源于stack exchange,提问作者sir-haver
相关产品推荐
相关产品推荐

