当前位置: 首页 > 科技观察

何时使用Map而不是普通JS对象

时间:2023-03-19 16:51:35 科技观察

JS普通对象{key:'value'}用于存储结构化数据。但有一件事我觉得很烦人:对象键必须是字符串(或很少使用的符号)。如果你使用数字作为键会发生什么?这种情况下没有报错:JS会隐式地将对象的key转为字符串。这种默认行为会失去类型一致性并且很难解决。但是ES6中的Map对象可以帮我们解决这类问题,LookSeeSee。1.Map接受任何类型的key前面说过,如果一个对象的key不是字符串或者符号,JS会隐式的将其转换为字符串。还好地图的key类型没有问题。1和2是numbersMap中的key,这些key的类型(number)保持不变。mpa中可以使用任何键类型:数字、布尔值、字符串和符号。booleansMap使用布尔值作为键,没问题。相反,布尔键对普通对象没有影响。让我们突破想象:是否使用整个对象作为地图的key,答案:是的。1.1对象作为键假设你需要存储一些与对象相关的数据,而不是将这些数据附加到对象本身。普通对象是不可能的。解决方案是使用一个对象值元组数组:kindOfMap是一个包含对象对和关联值的数组。这种方法最大的问题是key访问值的复杂度O(n),我们要遍历整个数组才能key获取想要的值。WeakMap(Map的特殊版本)不必经历所有这些麻烦来执行上述操作:它只接受对象作为键。Map和Weakmap的主要区别在于Weakmap允许对关键对象进行垃圾回收,从而防止内存泄漏。那么,使用Wea??kMap重构上面的代码就变得微不足道了:与Map不同,WeakMap只接受对象作为键,并且有一些较少的方法。2.map对键名没有限制。JS中的任何对象都继承原型对象的属性,普通对象也是如此。原型继承的属性如果被覆盖可能会破坏依赖于它们的代码:在对象参与者上定义的属性toString会覆盖原型继承的toString()方法。这打破了isObject()因为它依赖于toString()方法。检查通用对象从原型继承的属性和方法列表,避免使用这些方法名称定义自定义属性。例如,想象一个管理一些自定义字段的UI。用户可以通过指定名称和值来添加自定义字段:将自定义字段的状态存储到普通对象中会很方便:但用户可能会选择自定义字段名称,例如toString(如示例中所示),constructor等等,这可能会破坏我们的对象。不要在普通对象上使用用户输入的值作为键。地图不存在这个问题,并且键值名称不受限制:无论actorMap是否具有名为toString的属性,toString()方法都会起作用。3.地图是可迭代的。为了遍历普通对象的属性,必须使用其他辅助静态函数,例如Object.keys()或Object.entries():Object.entries(colorsHex)返回从对象中提取的键值对数组.但是,地图本身是可迭代的:colorsHexMap是可迭代的。它可以在任何接受可迭代对象的地方使用:for()循环、扩展运算符[...map]。map提供了返回一个可迭代对象的方法:map.keys()迭代键,map.values()迭代值4。地图的大小普通对象的另一个问题是您不能立即知道它包含的属性数量。要确定考试的规模,必须通过所有密钥以确定其数量。map提供了一个size属性,表示属性的个数。确定地图属性的数量甚至更简单:examsMap.size。总结PlainJS对象通常有利于保存结构化数据,但它们有一些局限性:只能以字符串或sybmol自身的对象属性为键,可能与从原型继承的属性键(例如toString、constructor等)发生冲突。对象不能作为key这些问题都可以通过map轻松解决。此外,它们还提供迭代器和易于大小查找等好处。不要将地图视为普通对象的替代品,而是对它们的补充。