ES6中Set和Map用法实例详解


Posted in Javascript onMarch 02, 2020

本文实例讲述了ES6中Set和Map用法。分享给大家供大家参考,具体如下:

Set

ES6提供了新的数据结构Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。

Set函数可以接受一个数组(或类似数组的对象)作为参数,用来初始化。

// 例一
var set = new Set([1, 2, 3, 4, 4]);
[...set]
// [1, 2, 3, 4]
 
var s = new Set();
 
[2, 3, 5, 4, 5, 2, 2].map(x => s.add(x));
 
for (let i of s) {
 console.log(i);
}
// 2 3 5 4

注:在Set内部,两个NaN是相等。两个对象总是不相等的。可以用length来检测

let set = new Set();
let a = NaN;
let b = NaN;
set.add(a);
set.add(b);
set // Set {NaN}
let set = new Set();
 
set.add({});
set.size // 1
 
set.add({});
set.size // 2
var arr=[
	{id:1,name:'叶落森'},
	{id:2,name:'叶落森'},
	{id:3,name:'叶落森'},
	{id:4,name:'叶落森'},
	{id:2,name:'叶落森'}
]
const s = new Set();
arr.forEach(x => s.add(x));
for (let i of s) {
 console.log(i);
}

ES6中Set和Map用法实例详解 

四个操作方法:

  • add(value):添加某个值,返回Set结构本身。
  • delete(value):删除某个值,返回一个布尔值,表示删除是否成功。
  • has(value):返回一个布尔值,表示该值是否为Set的成员。
  • clear():清除所有成员,没有返回值
let s = new Set();
s.add(1).add(2).add(2);
// 注意2被加入了两次
s.size // 2
s.has(1) // true
s.has(2) // true
s.has(3) // false
 
console.log(s.delete(2));//true
s.has(2) // false

set内部的元素可以遍历for...of...

遍历操作

Set 结构的实例有四个遍历方法,可以用于遍历成员。

  • keys():返回键名的遍历器
  • values():返回键值的遍历器
  • entries():返回键值对的遍历器
  • forEach():使用回调函数遍历每个成员

需要特别指出的是,Set的遍历顺序就是插入顺序。这个特性有时非常有用,比如使用 Set 保存一个回调函数列表,调用时就能保证按照添加顺序调用。

(1)keys()values()entries()

keys方法、values方法、entries方法返回的都是遍历器对象。由于 Set 结构没有键名,只有键值(或者说键名和键值是同一个值),所以keys方法和values方法的行为完全一致。

let set = new Set(['red', 'green', 'blue']);
 
for (let item of set.keys()) {
 console.log(item);
}
// red
// green
// blue
 
for (let item of set.values()) {
 console.log(item);
}
// red
// green
// blue
 
for (let item of set.entries()) {
 console.log(item);
}
// ["red", "red"]
// ["green", "green"]
// ["blue", "blue"]

Set 结构的实例默认可遍历,它的默认遍历器生成函数就是它的values方法。

这意味着,可以省略values方法,直接用for...of循环遍历 Set。

let set = new Set(['red', 'green', 'blue']);
 
for (let x of set) {
 console.log(x);
}
// red
// green
// blue

Set 结构的实例与数组一样,也拥有forEach方法,用于对每个成员执行某种操作,没有返回值

set = new Set([1, 4, 9]);
set.forEach((value, key) => console.log(key + ' : ' + value))
// 1 : 1
// 4 : 4
// 9 : 9

Map

Map结构提供了“值—值”的对应,是一种更完善的Hash结构实现。如果你需要“键值对”的数据结构,Map比Object更合适。它类似于对象,也是键值对的集合,但是“键”的范围不限于字符串,各种类型的值(包括对象)都可以当作键。

var m = new Map();
var o = {p: "Hello World"};
 
m.set(o, "content")
m.get(o) // "content"
 
m.has(o) // true
m.delete(o) // true
m.has(o) // false

注意,只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要非常小心。

var map = new Map();
map.set(['a'], 555);
map.get(['a']) // undefined

上面代码的set和get方法,表面是针对同一个键,但实际上这是两个值,内存地址是不一样的,因此get方法无法读取该键,返回undefined。

注:如果Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,包括0和-0。另外,虽然NaN不严格相等于自身,但Map将其视为同一个键。

实例属性和方法:size、set、get、has、delete、clear

遍历方法:keys()、values()、entries()、forEach()

const map = new Map([
 ['F', 'no'],
 ['T', 'yes'],
]);
 
for (let key of map.keys()) {
 console.log(key);
}
// "F"
// "T"
 
for (let value of map.values()) {
 console.log(value);
}
// "no"
// "yes"
 
for (let item of map.entries()) {
 console.log(item[0], item[1]);
}
// "F" "no"
// "T" "yes"
 
// 或者
for (let [key, value] of map.entries()) {
 console.log(key, value);
}
// "F" "no"
// "T" "yes"
 
// 等同于使用map.entries()
for (let [key, value] of map) {
 console.log(key, value);
}
// "F" "no"
// "T" "yes"

Map 结构转为数组结构,比较快速的方法是使用扩展运算符(...)。

const map = new Map([
 [1, 'one'],
 [2, 'two'],
 [3, 'three'],
]);
 
[...map.keys()]
// [1, 2, 3]
 
[...map.values()]
// ['one', 'two', 'three']
 
[...map.entries()]
// [[1,'one'], [2, 'two'], [3, 'three']]
 
[...map]
// [[1,'one'], [2, 'two'], [3, 'three']]

结合数组的map方法、filter方法,可以实现 Map 的遍历和过滤(Map 本身没有mapfilter方法)。

const map0 = new Map()
 .set(1, 'a')
 .set(2, 'b')
 .set(3, 'c');
 
const map1 = new Map(
 [...map0].filter(([k, v]) => k < 3)
);
// 产生 Map 结构 {1 => 'a', 2 => 'b'}
 
const map2 = new Map(
 [...map0].map(([k, v]) => [k * 2, '_' + v])
  );
// 产生 Map 结构 {2 => '_a', 4 => '_b', 6 => '_c'}

此外,Map 还有一个forEach方法,与数组的forEach方法类似,也可以实现遍历。

map.forEach(function(value, key, map) {
 console.log("Key: %s, Value: %s", key, value);
});

 

区别:

set是一种关联式容器,其特性如下:

  • set以RBTree作为底层容器
  • 所得元素的只有key没有value,value就是key
  • 不允许出现键值重复
  • 所有的元素都会被自动排序
  • 不能通过迭代器来改变set的值,因为set的值就是键

map和set一样是关联式容器,它们的底层容器都是红黑树,区别就在于map的值不作为键,键和值是分开的。它的特性如下:

  • map以RBTree作为底层容器
  • 所有元素都是键+值存在
  • 不允许键重复
  • 所有元素是通过键进行自动排序的
  • map的键是不能修改的,但是其键对应的值是可以修改的

 

weakset

WeakSet结构与Set类似,也是不重复的值的集合。

WeakSet和Set的区别:

  • WeakSet的成员只能是对象,而不能是其他类型的值
  • WeakSet中的对象都是弱引用,即垃圾回收机制不考虑WeakSet对该对象的引用,也就是说,如果其他对象都不再引用该对象,那么垃圾回收机制会自动回收该对象所占用的内存,不考虑该对象还存在于WeakSet之中。这个特点意味着,无法引用WeakSet的成员,因此WeakSet是不可遍历的。

WeakMap可以参考WeakSet

感兴趣的朋友可以使用在线HTML/CSS/JavaScript代码运行工具:http://tools.3water.com/code/HtmlJsRun测试上述代码运行效果。

更多关于JavaScript相关内容可查看本站专题:《JavaScript操作DOM技巧总结》、《JavaScript页面元素操作技巧总结》、《JavaScript事件相关操作与技巧大全》、《JavaScript查找算法技巧总结》、《JavaScript数据结构与算法技巧总结》、《JavaScript遍历算法与技巧总结》及《JavaScript错误与调试技巧总结》

希望本文所述对大家JavaScript程序设计有所帮助。

Javascript 相关文章推荐
javascript replace方法与正则表达式
Feb 19 Javascript
《JavaScript高级程序设计》阅读笔记(二) ECMAScript中的原始类型
Feb 27 Javascript
Javascript打印局部页面实例
Jun 21 Javascript
js实现倒计时及时间对象
Nov 15 Javascript
jstree的简单实例
Dec 01 Javascript
BootStrap table删除指定行的注意事项(笔记整理)
Feb 05 Javascript
关于Angular2 + node接口调试的解决方案
May 28 Javascript
VUE v-for循环中每个item节点动态绑定不同函数的实例
Sep 26 Javascript
Vue商品控件与购物车联动效果的实例代码
Jul 21 Javascript
ES10的13个新特性示例(小结)
Sep 23 Javascript
Vue自动构建发布脚本的方法示例
Jul 24 Javascript
vue print.js打印支持Echarts图表操作
Nov 13 Javascript
Vue父组件向子组件传值以及data和props的区别详解
Mar 02 #Javascript
js中addEventListener()与removeEventListener()用法案例分析
Mar 02 #Javascript
js构造函数constructor和原型prototype原理与用法实例分析
Mar 02 #Javascript
原生js实现日历效果
Mar 02 #Javascript
js中火星坐标、百度坐标、WGS84坐标转换实现方法示例
Mar 02 #Javascript
详解Vue中的Props与Data细微差别
Mar 02 #Javascript
微信小程序实现音频文件播放进度的实例代码
Mar 02 #Javascript
You might like
php过滤html标记属性类用法实例
2014/09/23 PHP
Yii使用migrate命令执行sql语句的方法
2016/03/15 PHP
thinkphp3.2嵌入百度编辑器ueditor的实例代码
2017/07/13 PHP
PHP自定义递归函数实现数组转JSON功能【支持GBK编码】
2018/07/17 PHP
使用PHP+Redis实现延迟任务,实现自动取消订单功能
2019/11/21 PHP
JQuery Ajax通过Handler访问外部XML数据的代码
2010/06/01 Javascript
用JQuery在网页中实现分隔条功能的代码
2012/08/09 Javascript
浅谈jquery中delegate()与live()
2015/06/22 Javascript
js表单元素checked、radio被选中的几种方法(详解)
2016/08/22 Javascript
实例解析jQuery工具函数
2016/12/01 Javascript
基于Bootstrap的网页设计实例
2017/03/01 Javascript
jQuery插件FusionWidgets实现的Bulb图效果示例【附demo源码下载】
2017/03/23 jQuery
JavaScript之Date_动力节点Java学院整理
2017/06/28 Javascript
关于Vue组件库开发详析
2018/07/01 Javascript
JavaScript解决浮点数计算不准确问题的方法分析
2018/07/09 Javascript
代码分析vue中如何配置less
2018/09/28 Javascript
JS与SQL方式随机生成高强度密码示例
2018/12/29 Javascript
js实现通过开始结束控制的计时器
2019/02/25 Javascript
Vue项目中配置pug解析支持
2019/05/10 Javascript
JavaScript 反射和属性赋值实例解析
2019/10/28 Javascript
Vue+Node实现商品列表的分页、排序、筛选,添加购物车功能详解
2019/12/07 Javascript
[41:37]DOTA2北京网鱼队选拔赛——冲击职业之路
2015/04/13 DOTA
Python中的yield浅析
2014/06/16 Python
Python中的字符串操作和编码Unicode详解
2017/01/18 Python
Python3.6使用tesseract-ocr的正确方法
2018/10/17 Python
python 列表递归求和、计数、求最大元素的实例
2018/11/28 Python
python3.x提取中文的正则表达式示例代码
2019/07/23 Python
解决安装新版PyQt5、PyQT5-tool后打不开并Designer.exe提示no Qt platform plugin的问题
2020/04/24 Python
荷兰照明、灯具和配件网上商店:dmlights
2019/08/25 全球购物
美国精品地毯网站:Boutique Rugs
2020/03/04 全球购物
初中体育教学反思
2014/01/14 职场文书
甜品店创业计划书
2014/08/14 职场文书
工伤事故赔偿协议书范文
2014/09/24 职场文书
2015年爱牙日活动总结
2015/03/23 职场文书
2016毕业实习单位评语大全
2015/12/01 职场文书
彻底卸载VMware虚拟机的超详细步骤记录
2022/07/15 Servers