停止在JavaScript中将对象用作哈希映射

开发 前端
Map是日常编程中比较常用的数据结构之一。它保留了可以很容易地通过其键来访问的键值对。在Java中,使用HashMap来实现这个目的是很明显的。然而,在JavaScript中,使用一个普通的对象来实现这个目标是非常方便的。

 Map是日常编程中比较常用的数据结构之一。它保留了可以很容易地通过其键来访问的键值对。在Java中,使用HashMap来实现这个目的是很明显的。然而,在JavaScript中,使用一个普通的对象来实现这个目标是非常方便的。

[[332917]]

 

  1. const map = {}; 
  2.  
  3. // 插入键值对 
  4. map['key1'] = 'value1'
  5. map['key2'] = 'value2'
  6. map['key3'] = 'value3'
  7.  
  8. // 检查map包含的键 
  9. if (map.hasOwnProperty('key1')) { 
  10.   console.log('Map contains key1'); 
  11.  
  12. // 通过特定的键获得值 
  13. console.log(map['key1']); 

但是JavaScript中有一个专门用于此目的的内置数据结构:Map。让我给你一些理由,让你喜欢Map而不是普通的对象。

1.更多键类型

对象只能有符号(symbols)或字符串。Map可以将任何类型的值作为键:对象,函数或基元(primitives)。

 

  1. const map = new Map(); 
  2. const myFunction = () => console.log('I am a useful function.'); 
  3. const myNumber = 666; 
  4. const myObject = { 
  5.   name'plainObjectValue'
  6.   otherKey: 'otherValue' 
  7. }; 
  8. map.set(myFunction, 'function as a key'); 
  9. map.set(myNumber, 'number as a key'); 
  10. map.set(myObject, 'object as a key'); 
  11.  
  12. console.log(map.get(myFunction)); // function as a key 
  13. console.log(map.get(myNumber)); // number as a key 
  14. console.log(map.get(myObject)); // object as a key 

2.更好地确定大小

Map提供了一个size属性,但一个普通对象的大小却必须通过艰难的方式来确定。确定Map的大小可以在O(1)时间内完成,而确定一个普通对象的大小则需要O(n)步。

 

  1. const map = new Map(); 
  2. map.set('someKey1', 1); 
  3. map.set('someKey2', 1); 
  4. ... 
  5. map.set('someKey100', 1); 
  6.  
  7. console.log(map.size) // 100, Runtime: O(1) 
  8.  
  9. const plainObjMap = {}; 
  10. plainObjMap['someKey1'] = 1; 
  11. plainObjMap['someKey2'] = 1; 
  12. ... 
  13. plainObjMap['someKey100'] = 1; 
  14.  
  15. console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n) 

3.更好的性能

对Map进行了优化,以便频繁地添加和删除条目。

此外,Map的条目数可以在恒定的时间内被检索,而一个普通对象的条目数必须被计算,这需要O(n)时间。

以我的Macbook Pro为例,这是一张有1000万个条目的Map的平均大小确定时间。

  • 普通JS对象: ~1.6 s
  • Map: < 1 ms

此外,它不需要将任何键转换为字符串,这可以节省很多时间。

 

4.直接迭代

对象必须通过获取键并对其进行迭代。另一方面,Map是可迭代的,这意味着它可以直接迭代。

 

  1. const map = new Map(); 
  2. map.set('someKey1', 1); 
  3. map.set('someKey2', 2); 
  4. map.set('someKey3', 3); 
  5.  
  6. for (let [key, value] of map) { 
  7.   console.log(`${key} = ${value}`); 
  8. // someKey1 = 1 
  9. // someKey2 = 2 
  10. // someKey3 = 3 
  11.  
  12. const plainObjMap = {}; 
  13. plainObjMap['someKey1'] = 1; 
  14. plainObjMap['someKey2'] = 2; 
  15. plainObjMap['someKey3'] = 3; 
  16.  
  17. for (let key of Object.keys(plainObjMap)) { 
  18.   const value = plainObjMap[key]; 
  19.   console.log(`${key} = ${value}`); 
  20. // someKey1 = 1 
  21. // someKey2 = 2 
  22. // someKey3 = 3 

5.key顺序

在ECMAScript 2015之前,一个对象的键不保证以任何特定的顺序出现。在Map上迭代保证键按插入顺序出现。

6.无键覆盖

一个普通对象由于其原型已经包含了一些键,你的键和对象已经包含的键之间可能会有冲突。Map在创建时不包含任何键。

注意:自ECMAScript 2015年起,你可以通过使用 Object.create(null) 来创建你的普通对象图来避免意外的键覆盖。

 

  1. const map = new Map(); 
  2. map.set('someKey1', 1); 
  3. map.set('someKey2', 2); 
  4. map.set('toString', 3); // No problem for Map 
  5.  
  6. const plainObjMap = new Map(); 
  7. plainObjMap['someKey1'] = 1; 
  8. plainObjMap['someKey2'] = 2; 
  9. plainObjMap['toString'] = 3; // Oops, native property 

 

 

责任编辑:华轩 来源: 今日头条
相关推荐

2009-03-13 13:58:10

Javascript哈希表伪哈希表

2023-10-04 07:25:59

JavaScriptpromises

2021-06-03 10:00:47

JavaScript 前端数克隆对象

2021-02-22 06:41:35

对象AutoMapper映射

2020-04-06 20:30:37

JavaScriptBoolean开发

2020-02-17 09:21:27

存储数据技术

2022-09-22 11:40:11

JavaScript数组开发

2009-04-22 09:00:55

IE8中文网址浏览器

2023-12-15 15:03:54

.NETAutoMapper对象映射工具

2015-11-24 09:53:22

AngularJSXMLJSON

2009-09-23 13:26:10

Hibernate对象

2020-08-19 08:29:22

JavaScript 对象函数

2023-11-21 15:23:15

JavaScript工具

2024-08-09 11:52:18

2010-07-30 10:58:03

Flex数据绑定

2018-12-19 19:30:46

JavaScript创建对象前端

2010-07-16 13:21:26

Perl哈希表

2023-06-02 15:42:51

JavaScript数据结构对象

2012-02-08 12:17:38

HibernateJava

2012-05-10 09:44:39

MongoDBJava
点赞
收藏

51CTO技术栈公众号