在前端开发中,我们经常需要处理键值对,比如将一些数据存储在一个对象中,但是对象的键只能是字符串类型,这就限制了它的使用范围。为了解决这个问题,ES6 新增了两个数据结构:Map 和 WeakMap。本文将详细介绍这两个数据结构的使用方法和区别。
Map
Map 是一个键值对的集合,其中的键和值可以是任意类型的数据,不仅仅限于字符串类型。可以将 Map 看作是一个更完善的对象,它提供了一些对象所不具备的方法,如 set()
、get()
、has()
、delete()
等。
基本使用
创建 Map 对象可以使用 new Map()
,也可以通过传入一个数组来初始化。以下是一个示例:
// javascriptcn.com 代码示例 // 创建空 Map 对象 const map = new Map(); // 通过传入数组来初始化 Map 对象 const map2 = new Map([ ['name', 'Tom'], ['age', 18], ['gender', 'male'], ]);
向 Map 对象中添加键值对可以使用 set()
方法,获取值可以使用 get()
方法,判断是否存在某个键可以使用 has()
方法,删除某个键可以使用 delete()
方法,清空 Map 对象可以使用 clear()
方法。以下是一个示例:
// javascriptcn.com 代码示例 const map = new Map(); // 添加键值对 map.set('name', 'Tom'); map.set('age', 18); map.set('gender', 'male'); // 获取值 console.log(map.get('name')); // Tom // 判断是否存在某个键 console.log(map.has('age')); // true // 删除某个键 map.delete('gender'); // 清空 Map 对象 map.clear(); console.log(map.size); // 0
迭代器
Map 对象提供了三个迭代器,分别是 keys()
、values()
、entries()
。其中 keys()
返回的是所有键的迭代器,values()
返回的是所有值的迭代器,entries()
返回的是所有键值对的迭代器。以下是一个示例:
// javascriptcn.com 代码示例 const map = new Map([ ['name', 'Tom'], ['age', 18], ['gender', 'male'], ]); // 迭代所有键 for (const key of map.keys()) { console.log(key); } // 迭代所有值 for (const value of map.values()) { console.log(value); } // 迭代所有键值对 for (const [key, value] of map.entries()) { console.log(`${key}: ${value}`); }
Map 与对象的区别
Map 对象与对象有很多相似之处,但也有一些区别。以下是它们之间的主要区别:
- Map 对象的键可以是任意数据类型,而对象的键只能是字符串类型。
- Map 对象的键值对是有序的,而对象的键值对是无序的。
- Map 对象的键值对个数可以通过
size
属性获取,而对象的键值对个数需要手动计算。
实战应用
Map 对象可以用于缓存数据,可以避免重复计算。以下是一个示例:
// javascriptcn.com 代码示例 const cache = new Map(); function fibonacci(n) { if (n <= 1) { return n; } if (cache.has(n)) { return cache.get(n); } const result = fibonacci(n - 1) + fibonacci(n - 2); cache.set(n, result); return result; }
WeakMap
WeakMap 是 Map 的一种特殊形式,它的键必须是对象,值可以是任意类型的数据。WeakMap 的特点是它的键是弱引用,当键对象被垃圾回收时,对应的键值对也会被自动删除。因此,WeakMap 可以用于存储临时数据,避免内存泄漏。
基本使用
创建 WeakMap 对象可以使用 new WeakMap()
,不支持传入数组来初始化。以下是一个示例:
const weakMap = new WeakMap();
向 WeakMap 对象中添加键值对可以使用 set()
方法,获取值可以使用 get()
方法,判断是否存在某个键可以使用 has()
方法,删除某个键可以使用 delete()
方法。以下是一个示例:
// javascriptcn.com 代码示例 const weakMap = new WeakMap(); // 添加键值对 const obj = {}; weakMap.set(obj, 'value'); // 获取值 console.log(weakMap.get(obj)); // value // 判断是否存在某个键 console.log(weakMap.has(obj)); // true // 删除某个键 weakMap.delete(obj);
WeakMap 的限制
由于 WeakMap 的键是弱引用,因此它有一些限制:
- WeakMap 的键必须是对象,不能是基本数据类型。
- WeakMap 的键不能被枚举,因此不能使用
keys()
、values()
、entries()
、forEach()
等方法。 - WeakMap 的键不能被直接获取,因此不能使用
size
属性。
实战应用
WeakMap 对象可以用于存储私有数据,避免被外部访问。以下是一个示例:
// javascriptcn.com 代码示例 const privateData = new WeakMap(); class Person { constructor(name, age) { privateData.set(this, { name, age }); } getName() { return privateData.get(this).name; } getAge() { return privateData.get(this).age; } } const person = new Person('Tom', 18); console.log(person.getName()); // Tom console.log(person.getAge()); // 18 console.log(privateData.get(person)); // undefined
总结
Map 和 WeakMap 是 ES6 中新增的两个数据结构,它们可以用于处理键值对。Map 对象的键可以是任意数据类型,而 WeakMap 对象的键必须是对象;Map 对象的键值对是有序的,而 WeakMap 对象的键值对是无序的;Map 对象的键值对个数可以通过 size
属性获取,而 WeakMap 对象的键值对个数不能直接获取。Map 对象可以用于缓存数据,WeakMap 对象可以用于存储私有数据。在实际开发中,根据不同的场景选择合适的数据结构,可以提高代码的可读性和性能。
来源:JavaScript中文网 ,转载请注明来源 本文地址:https://www.javascriptcn.com/post/657ab21dd2f5e1655d522abc