javaScript Map使用及注意事项

本文详细介绍了JavaScript中的Map数据结构,包括Map与Object的区别、Map的基本用法如set、get、has和delete等操作,以及Map在使用过程中的注意事项,如NAN作为键、Map的浅拷贝问题和作为hashMap的使用等。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Object与Map

在Es6之前,对象Object常常被用作map的功能,因为两者都可以实现按键存取一个值、删除键、检测一个键是否绑定了值。但是Object在使用上还是有一些不便之处,例如:

  1. 新增的键名可能会和Object原型链上的键名发生冲突。
  2. Object的键名只能是String和Symbol类型,事实上Symbol也是ES6新增的数据类型,因此在ES6之前,只能是String类型。
  3. Object键是无序的。
  4. Object键值对个数只能遍历计算,无法直接获取。

map用法

Map 作为ES6新增的两个数据结构之一(另一个为Set),相信大家并不陌生,简单回顾一下其主要用法:

属性

Map.prototype.constructor
返回一个函数,它创建了实例的原型。默认是Map函数。
Map.prototype.size
返回Map对象的键/值对的数量。

方法

Map.prototype.clear()
移除Map对象的所有键/值对 。
Map.prototype.delete(key)
如果 Map 对象中存在该元素,则移除它并返回 true;否则如果该元素不存在则返回 false。随后调用 Map.prototype.has(key) 将返回 false 。
Map.prototype.entries()
返回一个新的 Iterator 对象,它按插入顺序包含了Map对象中每个元素的 [key, value] 数组。
Map.prototype.forEach(callbackFn[, thisArg])
按插入顺序,为 Map对象里的每一键值对调用一次callbackFn函数。如果为forEach提供了thisArg,它将在每次回调中作为this值。
Map.prototype.get(key)
返回键对应的值,如果不存在,则返回undefined。
Map.prototype.has(key)
返回一个布尔值,表示Map实例是否包含键对应的值。
Map.prototype.keys()
返回一个新的 Iterator对象, 它按插入顺序包含了Map对象中每个元素的键 。
Map.prototype.set(key, value)
设置Map对象中键的值。返回该Map对象。
Map.prototype.values()
返回一个新的Iterator对象,它按插入顺序包含了Map对象中每个元素的值 。

其中最基础的方法是 set get has delete (增查改),其他是一些遍历的方法。使用时先使用new构造一个Map实例,再通过相应的方法操作。

let myMap = new Map();
 
let keyObj = {};
let keyFunc = function() {};
let keyString = 'a string';
 
// 添加键
myMap.set(keyString, "和键'a string'关联的值");
myMap.set(keyObj, "和键keyObj关联的值");
myMap.set(keyFunc, "和键keyFunc关联的值");
 
myMap.size; // 3
 
// 读取值
myMap.get(keyString);    // "和键'a string'关联的值"
myMap.get(keyObj);       // "和键keyObj关联的值"
myMap.get(keyFunc);      // "和键keyFunc关联的值"
 
myMap.get('a string');   // "和键'a string'关联的值"
                         // 因为keyString === 'a string'
myMap.get({});           // undefined, 因为keyObj !== {}
myMap.get(function() {}); // undefined, 因为keyFunc !== function () {}

注意点

NAN

NaN 可以作为Map对象的键。虽然 NaN 和任何值甚至和自己都不相等(NaN !== NaN 返回true),但NaN作为Map的键来说没有区别:

let myMap = new Map();
myMap.set(NaN, "not a number");

myMap.get(NaN); // "not a number"

let otherNaN = Number("foo");
myMap.get(otherNaN); // "not a number"
数组之间转换
let kvArray = [["key1", "value1"], ["key2", "value2"]];

// 使用常规的Map构造函数可以将一个二维键值对数组转换成一个Map对象
let myMap = new Map(kvArray);

myMap.get("key1"); // 返回值为 "value1"

// 使用Array.from函数可以将一个Map对象转换成一个二维键值对数组
console.log(Array.from(myMap)); // 输出和kvArray相同的数组

// 更简洁的方法来做如上同样的事情,使用展开运算符
console.log([...myMap]);

// 或者在键或者值的迭代器上使用Array.from,进而得到只含有键或者值的数组
console.log(Array.from(myMap.keys())); // 输出 ["key1", "key2"]
map复制的问题

Map 能像数组一样被复制:

let original = new Map([
  [1, 'one']
]);

let clone = new Map(original);

console.log(clone.get(1)); // one
console.log(original === clone); // false. 浅比较 不为同一个对象的引用

但是此时数据本身未被克隆,看另一个例子:

var map = new Map();
var obj1 = {"1":1}
var obj11 = {"11":11}
var point1 = obj1;
var point2 = obj11;

map.set(point1,point2)
console.log(map)
var map2 = new Map(map)
console.log(map2)

//obj1[1] = "one",
//console.log(map)
//console.log(map2)

前两次map和map2打印结果均为:
在这里插入图片描述
取消注释后,打印结果为:在这里插入图片描述
也就是说Map的拷贝是个浅拷贝

为map设置属性

为Map设置对象属性也是可以的,但是可能引起大量的混乱。

let wrongMap = new Map()
wrongMap['bla'] = 'blaa'
wrongMap['bla2'] = 'blaaa2'

console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }

这样做的话,它的行为会不符合预期:

wrongMap.has('bla')    // false
wrongMap.delete('bla') // false
console.log(wrongMap)  // Map { bla: 'blaa', bla2: 'blaaa2' }
hashMap使用

注意:map也可以用作hashmap功能,即实现无重复的键值对。在使用过程中,用一个对象的引用变量作为键值对时,实际上绑定的是该引用所指向的内存地址,因此即便该引用指向其他对象,也不会影响map中的键值对。

var map = new Map();
var obj1 = {"1":1}
var obj11 = {"11":11}
var obj2 = {"2":2}
var obj22 = {"22":22}

var point1 = obj1;
var point2 = obj11;

map.set(point1,point2)
console.log(map)

point1 = obj2;
point2 = obj22;
console.log(map)

两次的打印结果一样:
在这里插入图片描述
参考:https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Map

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值