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 相关文章推荐
input 输入框获得/失去焦点时隐藏/显示文字(jquery版)
Apr 02 Javascript
JavaScript 模拟类机制及私有变量的方法及思路
Jul 10 Javascript
js自动生成对象的属性示例代码
Oct 28 Javascript
jquery实现图片滚动效果的简单实例
Nov 23 Javascript
js实现鼠标滑过文字链接色彩变化的效果
May 06 Javascript
Node.js实现文件上传
Jul 05 Javascript
基于jQuery实现仿微博发布框字数提示
Jul 27 Javascript
JavaScript日期对象(Date)基本用法示例
Jan 18 Javascript
jquery图片放大镜效果
Jun 23 jQuery
layui 给数据表格加序号的方法
Aug 20 Javascript
vue实现前端分页完整代码
Jun 17 Javascript
Vue2项目中对百度地图的封装使用详解
Jun 16 Vue.js
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 数组的一个悲剧?
2011/05/11 PHP
php+mysql不用递归实现的无限级分类实例(非递归)
2014/07/08 PHP
php格式化日期实例分析
2014/11/12 PHP
php curl 模拟登录并获取数据实例详解
2016/12/22 PHP
javascript中直接引用Microsoft的COM生成Word
2014/01/20 Javascript
jQuery实现动画效果的简单实例
2014/01/27 Javascript
javascript常用代码段搜集
2014/12/04 Javascript
全面解析Bootstrap排版使用方法(文字样式)
2015/11/30 Javascript
在其他地方你学不到的jQuery小贴士和技巧(欢迎收藏)
2016/01/20 Javascript
使用jquery.form.js实现图片上传的方法
2016/05/05 Javascript
详解JSONObject和JSONArray区别及基本用法
2017/10/25 Javascript
AngularJS实现的省市二级联动功能示例【可对选项实现增删】
2017/10/26 Javascript
bootstrap+jquery项目引入文件报错的解决方法
2018/01/22 jQuery
vue动态删除从数据库倒入列表的某一条方法
2018/09/29 Javascript
详解小程序rich-text对富文本支持方案
2018/11/28 Javascript
react实现复选框全选和反选组件效果
2020/08/25 Javascript
Python下线程之间的共享和释放示例
2015/05/04 Python
使用Python的PIL模块来进行图片对比
2016/02/18 Python
Python常见加密模块用法分析【MD5,sha,crypt模块】
2017/05/24 Python
Python之自动获取公网IP的实例讲解
2017/10/01 Python
Python3计算三角形的面积代码
2017/12/18 Python
python 爬虫 批量获取代理ip的实例代码
2018/05/22 Python
Python 限制线程的最大数量的方法(Semaphore)
2019/02/22 Python
详解python使用turtle库来画一朵花
2019/03/21 Python
python实现生成Word、docx文件的方法分析
2019/08/30 Python
Python使用socket模块实现简单tcp通信
2020/08/18 Python
html5指南-2.如何操作document metadata
2013/01/07 HTML / CSS
技校毕业生自荐信范文
2014/03/07 职场文书
水污染治理工程专业自荐信
2014/06/21 职场文书
党的群众路线教育实践活动对照检查材料(教师)
2014/09/24 职场文书
社区国庆节活动总结
2015/03/23 职场文书
法院执行局工作总结
2015/08/11 职场文书
电力安全学习心得体会
2016/01/18 职场文书
如何起草一份正确的合伙创业协议书?
2019/07/04 职场文书
python入门学习关于for else的特殊特性讲解
2021/11/20 Python
Golang数据类型和相互转换
2022/04/12 Golang