企业🤖AI智能体构建引擎,智能编排和调试,一键部署,支持私有化部署方案 广告
[TOC] >[success] # Set集合与Map集合 <br/> ~~~ '数组'一直是'JavaScript'中唯一的'集合类型',也就是'数组类型','JavaScript'的'数组'的功能与其他 语言一样,但在'ES6标准'制定以前,由于可选的'集合类型'有限,'数组'使用的又是'数值型索引',因而经常 被创建'队列'和'栈'。如果开发者们需要使用'非数值型索引',就会用到'非数组对象'的'数据结构',而这 就是'Set集合'和'Map集合'的早期实现。 ~~~ <br/> ~~~ 集合类型: 1. 'Array' 2. 'Set' 3. 'Map' ~~~ <br/> >[success] ## Set集合 <br/> ~~~ 'Set集合'是一种'无重复元素的列表',开发者们一般不会逐一(东北话:'挨个')'读取数组中的元素', 也不太可能逐一(东北话:'挨个')'访问Set集合中的每个元素',通常的做法是'检测给定的值,在某集合中是否存在' ~~~ <br/> >[success] ## Map集合 <br/> ~~~ 'Map集合'内含多组'键值对',集合中每个元素分别存放着可访问的'键名'和它对应的'值','Map集合'经常被用于 '缓存频繁取用的数据'。 ~~~ <br/> >[success] ## ES5实现Set集合功能 / Map集合 <br/> ~~~ 在'ES6'发布之前,开发者们在'ES5'中用'非数组对象'的方式实现了类似的功能。 ~~~ <br/> 1. Set集合实现 ~~~ // 创建一个空对象,没有prototype属性的对象 let set = Object.create(null); // 创建一个set对象的属性 set.foo = true; if(set.foo){ // 检查属性是否存在 // 要执行的代码 } ~~~ <br/> 2. Map集合实现 ~~~ // 创建一个空对象,没有prototype属性的对象 let map = Object.create(null); // 创建一个Map对象的属性 map.foo = "bar"; // 获取已存值 let value = map.foo; console.log(value) // "bar" ~~~ <br/> >[warning] ## ES5实现Set集合、Map集合的一些问题 <br/> ~~~ 虽然能用'ES5'能实现出'Set集合'和'Map集合',但是非常的'局限性',如果对象的'属性'有限制的话, 例如,'所有对象的属性必须是字符串类型'、'每个键名(key)都是唯一的'。 ~~~ <br/> 1. 用`number类型`值作为对象的属性的问题 ~~~ // 创建一个空对象 let map = Object.create(null) // 用number类型值给对象创建属性,并且赋值 map[5] = 'foo' console.log(map[5]) // foo // 等同 console.log(map['5']) // foo ~~~ <br/> 2. 用`对象`作为`对象属性`的问题 ~~~ // 创建一个空对象 let map = Object.create(null) // 创建2个对象 let key1 = {} let key2 = {} // 用对象当做key值 map[key1] = 'foo' console.log(map[key1]) // foo console.log(map[key2]) // foo ~~~ <br/> `key1`和`key2`会被转换为`对象字符串`【Object,Object】,所以`map[key1]`和`map[key2]`引用的是同一个属性,实际上就是一个`假值`。对于`Map集合`如果他的值是`假值`,会被自动转换(强制转换)成`布尔值false`,`强制转换`本身没有问题,但是应用到下面的场合就会有问题了 <br/> ~~~ // 创建一个对象 let map = Object.create(null); map.count = 1; // 这里本意是想检查count是否存在,实际上检查的是count值否等于0 if(map.count){ // 要执行的代码 } ~~~ <br/> 在上面的例子中就有点让人不解,我们到底是判断的`map.count`是否存在,还是判断的`map.count`的值是否`非零`,就会很让人疑惑。 其实上面的例子中,由于值为`1`,所以判断条件进入了`if`中,如果想判断`对象的一个属性值是否存在`尽量不要这样写,可以使用以下的几个方法: <br/> 3. 判断对象属性是否存在 ~~~ 1. 使用`in`关键字,该方法可以判断对象的'自有属性'和'继承来的属性'是否存在。 var o = { x: 1 } console.log("x" in o) // true 自有属性存在 console.log("y" in o) // false 没有这个属性 console.log("toString" in o) // true,是一个继承属性 2. 使用对象的'hasOwnProperty()'方法,该方法只能判断'自有属性是否存在',对于'继承属性会返回false'。 var o = { x: 1 }; o.hasOwnProperty("x");    // true,自有属性中有x o.hasOwnProperty("y");    // false,自有属性中不存在y o.hasOwnProperty("toString"); // false,这是一个继承属性,但不是自有属性 ~~~