JavaScript-集合与映射
对象在Javascript编程中经常被用作映射和集合,但是却收到对字符串约束的限制。另外由于对象正常都会继承带名字的属性(如toString)等属性,这些属性也很明显不是为集合和映射准备的。
为此,ES6添加了真正的Set和Map类,接下来进行解析。
代码内的注释 !代表提示 => 模拟控制台输出
一、Set类
什么是集合
集合就是一组值,与数组类似。但与数组不同的是,集合没有索引或顺序,也不允许重复:一个值要么是集合的成员,要么不是;不可能在集合中出现多次
1.1 使用Set()构造函数创建集合对象
let s = new Set(); // ! 创建一个新的空集合,大小(size)为0
let t = new Set([1,s]) // ! 创建一个新的,有两个成员的集合
Set()构造函数的参数必须上一个可迭代的对象(也包括其他的集合)
let str = 'screen' // ! 创建字符串
let m = new Set(str) // ! 创建一个新的集合
console.log(m) // => {'s', 'c', 'r', 'e', 'n'}
1.2 集合不一定要在创建时初始化,也可以使用方法添加或删除元素
先上例子
let s = new Set(); // !创建一个空集合
s.add(2) // => 添加一个数值
s.add([1,2,3]).add(["a","b","c"]).add("2") // => 添加两个数组,一个字符串
s.delete([1,2,3]) // => false 集合中包含放是另一个数值
s.delete(2) // => true 删除成功,集合包含数值2
console.log(s.size) // => 3 集合大小
s.clear() // => 清空集合
关于这段代码的说明 ↓
-
add(value):
接收一个参数,将参数添加到集合中;如果参数是一个数组,它会把数组添加到集合中,而不是数组元素添加到集合里;add()始终返回调用他的集合。
如果想添加多个值,可以链缀调用add();例如↓
let s = new Set();
s.add([1,2,3]).add(["a","b","c"]).add(2)
-
delete(value):
删除集合中的一个元素,一次只能删除一个。delete返回一个布尔值,指定的值确实是一个集合元素,返回true,反之返回false。
注意点:集合成员是按照严格相等 === 来判断,集合可以是数值1,也可以是字符串 '1',这两个值不同;如果值是对象(数组、函数)也是 === 来比较。如果想删掉的话,必须传入该“数组”的引用 -
clear():
清除集合,没有返回值
在实际应用中,使用集合最重要的不是添加或删除元素,而是检查某个值是不是集合成员;使用has()方法。
-
has(value):
返回一个布尔值来指示对应的值value是否存在Set对象(集合)中
let s = new Set(['a', 'b']) // => 创建新集合
console.log(s.has('b')) // => true 因为有 "b" 这个成员
集合最重要的是它专门为成员测试做了优化,无论集合内有多少成员,has()方法都非常快。(数组的includes()方法也执行成员测试,但执行速度和数组大小相反,因此用数组作为集合比Set对象慢很多)
1.3 Set对象可以迭代,可以使用for...of循环枚举集合所有元素
let arr = [1,2,3] // => 创建数组
let s = new Set(arr) // => 创建新集合
for(item of s){
console.log(item) // 循环输出 1,2,3
}
1.4 因为Set是可迭代的,所有可以使用···扩展运算符
let arr = [1,2,3] // => 创建数组
let s = new Set(arr) // => 创建新集合
console.log(...s) // => 1 2 3
1.5 因为Set是可迭代的,也有forEach()方法,与数组类似
let arr = [1,2,3]
let s = new Set(arr) // => 创建新集合
s.forEach(function (item) {
console.log(item) // => 1 2 3
})
二、Map类
Map对象表示一组被称为键的值,其中每个键都关联着(或映射到)另一个值。映射类似于数组,只不过他不用连续的整数作为键,而是运行任何值作为索引。于数组类似,映射速度也很快(没有通过索引访问数组那么快)
2.1 通过Map()构造函数创建映射对象,把关联的键和值写成数组的形式
let m = new Map();; // => 创建一个新的空映射
let n = new Map([ // 初始化新映射
["one",1],
["two",2]
])
Map()构造函数的参数是一个可迭代的对象,包含两个元素的数组[key,value]键值对。正常使用中,通常把关联的键或值写成数组的数组的形式;也可以使用Map()构造函数复制其他映射,或者从已有的对象复制属性名和值:
let n = new Map([ // 初始化新映射
["one",1],
["two",2]
])
// ! 也可以使用Map()构造函数复制其他映射
let copy = new Map(n) ` // 复制新映射,有和n一样的键和值
n.delete("one")
// ! 也可以从已有对象复制属性名和值
let o = { x:1, y:2 } // 初始化新对象
let p = new Map(Object.entries(o)) // => 相当于 new Map([["x",1],["y",2]])
-
set()
: 增加、修改;与集合的add()方法类似,可以链缀调用
n.set("there",4) // => 添加映射键“there”和值4
n.set("there",3) // => 修改映射键“there”和值3
-
get()
: 获取;用来查询关联的值
console.log(n.get("there")) // => 输出与there相关的值
-
has()
: 判断里面有没有这个值 true / false
console.log(n.has("name")) // => false 判断映射是否有键“name”
-
delete()
:** 删除指定键**
n.delete("two") // ! ["two",2],这个键值对被删除了
-
clear()
: 清除 (慎用,和集合的clear一样)
与集合一样,任何JavaScript值都可以做完映射的键和值,包括null、undefined、NaN以及对象和数组等引用数据类型;也和集合一样,安装全等于 === 而非相等于。
2.2 映射对象是可迭代的,迭代的值上一个或两个元素的数组,可跌带也可以使用...扩展运算符
let n = new Map([ // 初始化新映射
["one",1],
["two",2]
])
console.log([...n]) // => 输出
console.log(...n) // => ['one', 1] (2) ['two', 2]
console.log(n) // => {'one' => 1, 'two' => 2}
for(let [key, value] of n){
console.log(key, value)
}
集合和映射都是安装插入的先后顺序迭代的,迭代第一个键值对是最早添加到映射中的,最后一个键值对是最晚添加的。
如果只是想迭代映射的键或关联的值,可以用keys()
和values()
方法。
keys()
取出Map里面所有的键
console.log(n.keys()) // ! 只会单独取出键
values()
取出Map里面所有的值
console.log(n.values()) // ! 只会单独取出值
还有一个entries()
方法返回所有可迭代对象的键值对
entries()
:取出里面所有的键和值 等价于 [...n]
console.log(n.entries()) // ! 全部取出来,和直接打印n差不多,意义不大
2.3 映射同样也实现了forEach()方法
let n = new Map([ // 初始化新映射
["one",1],
["two",2]
])
n.forEach((value,key)=> {
console.log(key , value)
})
注意:是(value,key),与for...of相反。
发表评论 (审核通过后显示评论):