ES6中如何使用Set和WeakSet


Posted in Javascript onMarch 10, 2016

ES6中提供了两新数据结构-Set和WeakSet。Set是类似于数组,但是成员变量的值都是唯一的,没有重复的值。WeakSet也是不重复的值的集合,但是只能用来存放对象。

一、Set使用

(1)Set本身提供了一个构造函数,用来生成Set数据结构。

var s = new Set();
[2,2,2,5,8,16,2,1].map(x => s.add(x))

for(i of s){console.log(i)}
//2,5,8,16,1

(2)Set()函数可以接受一个数组,作为构造参数,用于做初始化。

var s = new Set([1,2,3,4,2,4,3]);
[...s]
//[1,2,3,4]

注意:向Set中加入值的时候不会发生类型转换,所以5和”5”是两个不同的值,Set内部判断两个值是否相等,使用的是 ===,这就意味着这两个对象总是不相等。唯一列外的是NaN本身(精确相等运算符认为NaN不等于自身)

let set = new Set();
set.add({})
set.size//1
set.add({})
set.size//2

则,上面的代码表示,由于这两个空对象不是精确相等,所以是两个不同的值。

(3)Set的方法和属性

(3.1)Set的属性

Set.prototype.size:返回Set实例的成员数量。
Set.prototype.constructor:默认的构造Set函数。

(3.2)Set的操作啊函数

add(value):添加某个值,返回Set结构本身。
delete(value):删除某个值,返回一个布尔值,表示删除成功。
has(value):返回一个布尔值,表示参数是否为Set的成员。
clear():清除所有成员,没有返回值。

var set = new Set();
set.add(1).add(2).add(22).add(22);
set.size//3

set.hae(22)//true
set.has(4)//false
set.delete(2)//true

(3.3)Set遍历操作

Set有四个遍历方法。可以用于遍历成员。
keys() :返回一个键名的遍历器
values() :返回一个值的遍历器
entries() :返回一个键值对的遍历器
forEach():使用回调函数遍历每个成员

注意:由于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"]

//所以,entries方法返回的遍历器同时包括键名和值,所以每次输出的是一个数组。其实成员都是完全一样的。

注意:Set默认的可遍历,其默认遍历器生成函数就是它的values方法。
这就意味着,可以省略values方法,直接用for…of遍历。

var set = new Set([1,2,3,4]);
for(let x of set){
console.log(x);
}
//1
//2
//3
//4

如果使用扩展运算符(…)内部使用for…of 循环,所以也可以用于Set结构。

let set = new Set(['red','green','blue']);
let arr = [...set];
//['red','green','blue'];

(3.4)Set实现并集,交集,差集

let set1 = new Set([1,2,3,4,5,6]);
let set2 = new Set([4,5,6,7,8,9]);

//并集
let union = new Set([...set1,...set2]);
//[1,2,3,4,5,6,7,8,9]
//交集
let intersect = new Set([...set1].filter(x => b.has(s)));
//[4,5,6]
//差集
let intersect = new Set([...set1].filter(x => !b.has(s)));
//[1,2,3,4]

(3.5)Set实现forEach的使用

let set = new Set([1,2,3,4,5,6]);
set.forEach(value,key)=>consloe.log(vlaue+1);
//2
//3
//4
//5
//6
//7

注意:forEach方法的参数就是一个处理函数,该函数依次为(键值,键名)集合本身。另外,forEach方法还有第二个参数,表示绑定this的对象。

二、WeakSet使用

WeakSet类似于Set,也是不重复的值的集合。但是它只能用于存储对象。而不能是其他类型的值。
WeakSet是一个个构造函数。可以接受数组和类似数组的对象作为参数。(实际上,任何具作为iterable接口的对象都可以作为WeakSet的参数)。该数组的所有成员都会自动成为WeakSet的实例对象的成员。
var a = new [[1,2],[3,4]];
var ws = new WeakSet(a);

var ws = new WeakSet();
ws.add(1);//TypeError:Invalid value used in weak set 
ws.add(Symbol);//TypeError:Invalid value used in weak set

添如一个数值和一个Symbol,结果同时报错。

WeakSet结构有以下的上方法
WeakSet.protoptype.add(value):向WeakSet实例添加一个新成员。
WeakSet.protoptype.delete(value):删除WeakSet实例指定成员。
WeakSet.protoptype.has(value):返回一个布尔值,表示某个值是否在WeakSet实例中。

var ws = new WeakSet();
var obj = {};
var foo = {};
ws.add(window);
ws.add(obj);
ws.has(window);//true
ws.has(foo);false
ws.delete(window);//true
ws.has(window);//false

WeakSet 不能遍历,是因为成员都是弱引用,随时可能消失,遍历不能保证成员的存在。可能刚刚遍历结束,成员就取不到了。WeakSet的一个用处是存储DOM节点,而不用担心这些节点从文档移除时,会引起内存的泄露。

Javascript 相关文章推荐
Jquery 高亮显示文本中重要的关键字
Dec 24 Javascript
jquery快捷动态绑定键盘事件的操作函数代码
Oct 17 Javascript
前端开发过程中浏览器版本的两种判定方法
Oct 30 Javascript
JavaScript中的对象序列化介绍
Dec 30 Javascript
js实现数组转换成json
Jun 26 Javascript
jQuery实现form表单元素序列化为json对象的方法
Dec 09 Javascript
浅析jQuery 3.0中的Data
Jun 14 Javascript
微信小程序 Record API详解及实例代码
Sep 30 Javascript
详解基于node的前端项目编译时内存溢出问题
Aug 01 Javascript
基于vue.js中关于下拉框的值默认及绑定问题
Aug 22 Javascript
详解Vue.directive 自定义指令
Mar 27 Javascript
vue.js页面加载执行created,mounted的先后顺序说明
Nov 07 Javascript
解析javascript瀑布流原理实现图片滚动加载
Mar 10 #Javascript
javascript实现可键盘控制的抽奖系统
Mar 10 #Javascript
基于javascript制作微信聊天面板
Aug 09 #Javascript
关于Bootstrap弹出框无法调用问题的解决办法
Mar 10 #Javascript
TypeScript Type Innference(类型判断)
Mar 10 #Javascript
JavaScript File分段上传
Mar 10 #Javascript
ES6中非常实用的新特性介绍
Mar 10 #Javascript
You might like
PHP的一个完整SMTP类(解决邮件服务器需要验证时的问题)
2006/10/09 PHP
PHP令牌 Token改进版
2008/07/18 PHP
PHPnow安装服务[apache_pn]失败的问题的解决方法
2010/09/10 PHP
php生成扇形比例图实例
2013/11/06 PHP
PHP实现手机号码中间四位用星号(*)隐藏的自定义函数分享
2014/09/27 PHP
php使用curl出现Expect:100-continue解决方法
2015/03/03 PHP
php使用mysqli和pdo扩展,测试对比连接mysql数据库的效率完整示例
2019/05/09 PHP
JS的递增/递减运算符和带操作的赋值运算符的等价式
2007/12/08 Javascript
北京奥运官方网站幻灯切换效果flash版打包下载
2008/01/30 Javascript
jQuery的实现原理的模拟代码 -1 核心部分
2010/08/01 Javascript
查看大图功能代码jquery版
2013/11/05 Javascript
JavaScript两种跨域技术全面介绍
2014/04/16 Javascript
JS实现搜索关键词的智能提示功能
2017/07/07 Javascript
ES6学习之变量的两种命名方法示例
2017/07/18 Javascript
AngularJS实现的JSONP跨域访问数据传输功能详解
2017/07/20 Javascript
vue插件vue-resource的使用笔记(小结)
2017/08/04 Javascript
解决Vue2.0中使用less给元素添加背景图片出现的问题
2018/09/03 Javascript
移动端 Vue+Vant 的Uploader 实现上传、压缩、旋转图片功能
2019/06/10 Javascript
vue跳转页面的几种方法(推荐)
2020/03/26 Javascript
在antd中setFieldsValue和defaultVal的用法
2020/10/29 Javascript
python使用matplotlib画饼状图
2018/09/25 Python
对django xadmin自定义菜单的实例详解
2019/01/03 Python
pyhanlp安装介绍和简单应用
2019/02/22 Python
python使用HTMLTestRunner导出饼图分析报告的方法
2019/12/30 Python
python 发送邮件的示例代码(Python2/3都可以直接使用)
2020/12/03 Python
Python调用SMTP服务自动发送Email的实现步骤
2021/02/07 Python
HTML5中使用postMessage实现Ajax跨域请求的方法
2016/04/19 HTML / CSS
瑞贝卡·泰勒官方网站:Rebecca Taylor
2016/09/24 全球购物
国际性能运动服装品牌:Dare 2b
2018/07/27 全球购物
思想专业自荐信范文
2013/12/25 职场文书
三年级数学教学反思
2014/01/31 职场文书
银行简历自我评价
2014/02/11 职场文书
励志语录:你若不勇敢,谁替你坚强
2019/11/08 职场文书
详解Java实践之适配器模式
2021/06/18 Java/Android
java基础——多线程
2021/07/03 Java/Android
详细聊聊Oracle表碎片对性能有多大的影响
2022/03/19 Oracle