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中的parseInt和parseFloat区别
Jul 12 Javascript
javascript显示用户停留时间的简单实例
Aug 05 Javascript
jQuery中extend函数的实现原理详解
Feb 03 Javascript
JS版元素周期表实现方法
Aug 05 Javascript
浅谈js在html中的加载执行顺序,多个jquery ready执行顺序
Nov 26 Javascript
JQuery学习总结【一】
Dec 01 Javascript
JS在浏览器中解析Base64编码图像
Feb 09 Javascript
vue组件实现进度条效果
Jun 06 Javascript
JS中使用react-tooltip插件实现鼠标悬浮显示框
May 15 Javascript
JS实现返回上一页并刷新页面的方法分析
Jul 16 Javascript
这15个Vue指令,让你的项目开发爽到爆
Oct 11 Javascript
Vue SSR 即时编译技术的实现
May 06 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设计模式之迭代器模式的深入解析
2013/06/13 PHP
PHP SPL使用方法和他的威力
2013/11/12 PHP
搭建Vim为自定义的PHP开发工具的一些技巧
2015/12/11 PHP
php二维数组按某个键值排序的实例讲解
2019/02/15 PHP
JQUERY复选框CHECKBOX全选,取消全选
2008/08/30 Javascript
用Javascript数组处理多个字符串的连接问题
2009/08/20 Javascript
基于PHP和Mysql相结合使用jqGrid读取数据并显示
2015/12/02 Javascript
js canvas实现擦除动画
2016/07/16 Javascript
Vue.js每天必学之方法与事件处理器
2016/09/06 Javascript
BootstrapTable refresh 方法使用实例简单介绍
2017/02/20 Javascript
jsonp跨域请求详解
2017/07/13 Javascript
原生js中ajax访问的实例详解
2017/09/19 Javascript
vue 系列——vue2-webpack2框架搭建踩坑之路
2017/12/22 Javascript
JS/jQuery实现DIV延时几秒后消失或显示的方法
2018/02/12 jQuery
ES6之模版字符串的具体使用
2018/05/17 Javascript
Vue父子组建的简单通信之控制开关Switch的实现
2018/06/04 Javascript
浅析Proxy可以优化vue的数据监听机制问题及实现思路
2018/11/29 Javascript
Element UI框架中巧用树选择器的实现
2018/12/12 Javascript
JS控制GIF图片的停止与显示
2019/10/24 Javascript
如何基于原生javaScript生成带图片的二维码
2019/11/21 Javascript
将Python中的数据存储到系统本地的简单方法
2015/04/11 Python
简单实现python画圆功能
2018/01/25 Python
Php多进程实现代码
2018/05/07 Python
Python实现读取SQLServer数据并插入到MongoDB数据库的方法示例
2018/06/09 Python
Python中的取模运算方法
2018/11/10 Python
Python实现插入排序和选择排序的方法
2019/05/12 Python
10行Python代码实现Web自动化管控的示例代码
2020/08/14 Python
django中ImageField的使用详解
2020/12/21 Python
Python爬取网站图片并保存的实现示例
2021/02/26 Python
美国香薰蜡烛品牌:PADDYWAX
2018/10/06 全球购物
Speedo速比涛法国官方网站:泳衣、泳镜、泳帽、泳裤
2019/07/30 全球购物
传播学专业毕业生自荐信
2013/11/04 职场文书
手机被没收检讨书
2014/02/22 职场文书
2015年小学教导处工作总结
2015/05/26 职场文书
有关朝花夕拾的读书笔记
2015/06/29 职场文书
python 通过使用Yolact训练数据集
2021/04/06 Python