ThinkChat2.0新版上线,更智能更精彩,支持会话、画图、阅读、搜索等,送10W Token,即刻开启你的AI之旅 广告
## 一、set 1、定义 ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。 ``` const s = new Set(); [2, 3, 5, 4, 5, 2, 2].forEach(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4 ``` Set函数可以接受一个数组(或者具有 iterable 接口的其他数据结构)作为参数,用来初始化。 ``` // 例一 const set = new Set([1, 2, 3, 4, 4]); [...set] // [1, 2, 3, 4] // 例二 const items = new Set([1, 2, 3, 4, 5, 5, 5, 5]); items.size // 5 // 例三 const set = new Set(document.querySelectorAll('div')); set.size // 56 // 类似于 const set = new Set(); document .querySelectorAll('div') .forEach(div => set.add(div)); set.size // 56 ``` 2、属性 Set 结构的实例有以下属性。 ``` Set.prototype.constructor:构造函数,默认就是Set函数。 Set.prototype.size:返回Set实例的成员总数。 ``` 3、方法 Set 实例的方法分为两大类:操作方法(用于操作数据)和遍历方法(用于遍历成员) ``` Set.prototype.add(value):添加某个值,返回 Set 结构本身。 Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功。 Set.prototype.has(value):返回一个布尔值,表示该值是否为Set的成员。 Set.prototype.clear():清除所有成员,没有返回值。 ``` ``` Set.prototype.keys():返回键名的遍历器 Set.prototype.values():返回键值的遍历器 Set.prototype.entries():返回键值对的遍历器 Set.prototype.forEach():使用回调函数遍历每个成员 ``` ## 二、map JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。了解决这个问题,ES6 提供了 Map 数据结构。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。也就是说,Object 结构提供了“字符串—值”的对应,Map 结构提供了“值—值”的对应,是一种更完善的 Hash 结构实现。如果你需要“键值对”的数据结构,Map 比 Object 更合适。 1、定义 作为构造函数,Map 也可以接受一个数组作为参数。该数组的成员是一个个表示键值对的数组。 ``` const m = new Map(); const o = {p: 'Hello World'}; m.set(o, 'content') m.get(o) // "content" m.has(o) // true m.delete(o) // true m.has(o) // false ``` 2、属性 ``` size 属性 ``` `size`属性返回 Map 结构的成员总数。 ~~~javascript const map = new Map(); map.set('foo', true); map.set('bar', false); map.size // 2 ~~~ 3、方法 ``` Map.prototype.set(key, value) Map.prototype.get(key) Map.prototype.has(key) Map.prototype.delete(key) Map.prototype.clear() ``` ``` Map.prototype.keys():返回键名的遍历器。 Map.prototype.values():返回键值的遍历器。 Map.prototype.entries():返回所有成员的遍历器。 Map.prototype.forEach():遍历 Map 的所有成员。 ``` 4、与其他数据结构互换 Map 转为数组:Map 转为数组最方便的方法,就是使用扩展运算符(...): ``` const myMap = new Map() .set(true, 7) .set({foo: 3}, ['abc']); [...myMap] // [ [ true, 7 ], [ { foo: 3 }, [ 'abc' ] ] ] ``` 数组 转为 Map:将数组传入 Map 构造函数,就可以转为 Map。 ``` new Map([ [true, 7], [{foo: 3}, ['abc']] ]) // Map { // true => 7, // Object {foo: 3} => ['abc'] // } ``` Map 转为对象:如果所有 Map 的键都是字符串,它可以无损地转为对象。 ``` function strMapToObj(strMap) { let obj = Object.create(null); for (let [k,v] of strMap) { obj[k] = v; } return obj; } const myMap = new Map() .set('yes', true) .set('no', false); strMapToObj(myMap) // { yes: true, no: false } ``` 对象转为 Map:对象转为 Map 可以通过Object.entries()。 ``` let obj = {"a":1, "b":2}; let map = new Map(Object.entries(obj)); ``` Map 转为 JSON:Map 转为 JSON 要区分两种情况。 一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。 ``` function strMapToJson(strMap) { return JSON.stringify(strMapToObj(strMap)); } let myMap = new Map().set('yes', true).set('no', false); strMapToJson(myMap) // '{"yes":true,"no":false}' ``` 另一种情况是,Map 的键名有非字符串,这时可以选择转为数组 JSON。 ``` function mapToArrayJson(map) { return JSON.stringify([...map]); } let myMap = new Map().set(true, 7).set({foo: 3}, ['abc']); mapToArrayJson(myMap) // '[[true,7],[{"foo":3},["abc"]]]' ``` JSON 转为 Map:JSON 转为 Map,正常情况下,所有键名都是字符串。 ``` function jsonToStrMap(jsonStr) { return objToStrMap(JSON.parse(jsonStr)); } jsonToStrMap('{"yes": true, "no": false}') // Map {'yes' => true, 'no' => false} ```