我们还是从一些现有的需求和问题出发,为什么会有set,他的存在是为了解决什么问题?

我们看一个这样的例子,为一个对象添加键值对

 var obj = Object.create( null );
obj[5] = 'ghostwu';
console.log( obj["5"] ); //ghostwu
console.log( obj[5] ); //ghostwu

以null为原型对象,创建一个对象,给对象添加一个数字键5, 在输出的时候,数字键5会自动转换成字符键"5",这样的自动类型转换,会产生很多隐式问题.

 var obj = Object.create( null );
var key1 = {};
var key2 = {};
obj[key1] = "ghostwu";
console.log( obj[key1] ); //ghostwu
console.log( obj[key2] ); //ghostwu

上面这个程序中,空对象在作为键的情况下, 发生类型转换,变成对象对应的字符串 '[object Object]',所以obj[key1]和obj[key2]指向的是同一个引用

obj = {
num : 0
}
if ( obj.num ) {
alert( '存在这个变量' );
}

判断一个对象是否存在某个属性,如果num是非false的值,上面就没有问题,现在num为0,对象是存在num这个值的,但是用if判断的时候,结果就不对了

es6的set集合,就不会产生键的变量类型转换.

set的基本使用方法:

set是一种有序列表,其中含有一些相互独立的非重复的值.

调用new Set()创建Set集合,如果需要为set集合添加值,用add方法, size属性获取集合的元素个数

 var set = new Set();
set.add( 5 );
set.add( '5' );
console.log( set.size ); //

5和'5'是两个不同的值

 var set = new Set();
var key1 = {};
var key2 = {};
set.add( key1 );
set.add( key2 );
console.log( set.size ); //2

key1和key2是两个独立的值,尽管他们都是空对象

添加一个同名的值操作,会被忽略

 var set = new Set();
set.add( 5 );
set.add( '5' );
set.add( 5 ); //忽略
console.log( set.size ); //

因为set集合的值是非重复的

has(): 检测set集合是否存在某个值:

 var set = new Set();
set.add( 5 );
set.add( '5' );
console.log( set.has( '5' ) ); //true
console.log( set.has( 5 ) ); //true
console.log( set.has( 'wu' ) ); //false

delete: 删除某个值, clear:清空set

 var set = new Set();
set.add( 5 );
set.add( '5' ); console.log( set.has( '5' ) ); //true
set.delete( '5' );
console.log( set.has( '5' ) ); //false console.log( set.has( 5 ) ); // true
console.log( set.size ); // set.clear();
console.log( set.has( 5 ) ); // false
console.log( set.size ); //

利用set的特性,可以把数组去重复

 var set = new Set( [ 10, 20, 30, 10, 10, 20, 40 ] );
console.log( set.size ); //

Set跟数组一样,也支持forEach方法,参数也是一样

 var set = new Set( [ 'ghostwu', '悟空', '八戒' ] );
set.forEach( function( val, key, cur ){
console.log( key, val, cur );
} );

键与值一样,数组的键是数字索引,这点不同。所以Set不能像用数组索引那样去取值,但是我们可以把Set转换成数组,而且能利用set的非重复特性,把数组去重复

 var set = new Set( [ 10, 20, 30, 10, 10, 20, 40 ] );
var arr = [...set];
console.log( arr ); // 10, 20, 30, 40

封装成去重复的函数

 function unique( arr ){
return [...new Set( arr )];
}
var arr = [ 'abc', 'ghostwu', 'abc', 'ghostwu' ];
console.log( unique( arr ) ); //abc, ghostwu

应用set的特性,做一个多人抽奖的小程序,确保每一个人抽到的奖项都是唯一的

 <!DOCTYPE html>
<html lang="en">
<head>
<meta charset="UTF-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta http-equiv="X-UA-Compatible" content="ie=edge">
<title>Document</title>
<style>
#box {
width: 300px;
height: 100px;
line-height: 100px;
font-size: 30px;
text-align: center;
border: 1px solid #aaa;
box-shadow: 2px 2px 3px #ccc;
}
</style>
</head>
<body>
<div id="box"></div>
<input type="button" value="小明">
<input type="button" value="小B">
<input type="button" value="小A">
<input type="button" value="小新">
<input type="button" value="小叶">
<script>
var aPrize = ['小米', 'iphone5', 'iphone6', 'iphone7', 'iphone8'],
aInput = document.querySelectorAll("input"),
oBox = document.querySelector("#box"),
set = new Set(), rand = null;
aInput.forEach((ele, ind, cur) => {
ele.flag = false;
ele.addEventListener('click', () => {
if ( !ele.flag ) {
rand = Math.floor(Math.random() * aPrize.length);
if (!set.has(rand)) {
set.add(rand);
} else {
while (set.has(rand)) {
rand = Math.floor(Math.random() * aPrize.length);
if (!set.has(rand)) {
set.add(rand);
break;
}
}
}
oBox.innerHTML = aPrize[rand];
ele.flag = true;
ele.value = '您已经抽过了';
}
}, ele);
});
</script>
</body>
</html>

[js高手之路] es6系列教程 - Set详解与抽奖程序应用实战的更多相关文章

  1. [js高手之路] es6系列教程 - Map详解以及常用api

    ECMAScript 6中的Map类型是一种存储着许多键值对的有序列表.键值对支持所有的数据类型. 键 0 和 ‘0’会被当做两个不同的键,不会发生强制类型转换. 如何使用Map? let map = ...

  2. [js高手之路] es6系列教程 - 对象功能扩展详解

    第一:字面量对象的方法,支持缩写形式 //es6之前,这么写 var User = { name : 'ghostwu', showName : function(){ return this.nam ...

  3. [js高手之路] es6系列教程 - 迭代器,生成器,for...of,entries,values,keys等详解

    接着上文[js高手之路] es6系列教程 - 迭代器与生成器详解继续. 在es6中引入了一个新的循环结构for ....of, 主要是用来循环可迭代的对象,那么什么是可迭代的对象呢? 可迭代的对象一般 ...

  4. [js高手之路] es6系列教程 - 迭代器与生成器详解

    什么是迭代器? 迭代器是一种特殊对象,这种对象具有以下特点: 1,所有对象都有一个next方法 2,每次调用next方法,都会返回一个对象,该对象包含两个属性,一个是value, 表示下一个将要返回的 ...

  5. [js高手之路] es6系列教程 - promise常见用法详解(resolve,reject,catch,then,all,race)

    关于promise我在之前的文章已经应用过好几次,如[js高手之路]Node.js+jade+express+mongodb+mongoose+promise实现todolist,本文就来讲解下pro ...

  6. [js高手之路] es6系列教程 - 函数的默认参数详解

    在ES6之前,我们一般用短路表达式处理默认参数 function show( a, b ){ var a = a || 10; var b = b || 20; console.log( a, b ) ...

  7. [js高手之路] es6系列教程 - 箭头函数详解

    箭头函数是es6新增的非常有意思的特性,初次写起来,可能会觉得别扭,习惯之后,会发现很精简. 什么是箭头函数? 箭头函数是一种使用箭头( => )定义函数的新语法, 主要有以下特性: 不能通过n ...

  8. [js高手之路] es6系列教程 - var, let, const详解

    function show( flag ){ console.log( a ); if( flag ){ var a = 'ghostwu'; return a; } else { console.l ...

  9. [js高手之路] es6系列教程 - 不定参数与展开运算符(...)

    三个点(...)在es6中,有两个含义: 用在形参中, 表示传递给他的参数集合, 类似于arguments, 叫不定参数. 语法格式:  在形参面前加三个点( ... ) 用在数组前面,可以把数组的值 ...

随机推荐

  1. JavaScript基础-流程控制-if

    流程控制基本概念 默认情况下,程序的运行流程是这样的:运行程序后,系统会按书写从上至下顺序执行程序中的每一行代码,但是这并不能满足我们所有的开发需求 1.png 实际开发中, 我们需要根据不同的条件执 ...

  2. BotVS开发基础—2.11 API绘制图表

    代码 import time chart = { '__isStock': True, # 标记是否为一般图表,有兴趣的可以改成 false 运行看看. 'tooltip': {'xDateForma ...

  3. 【渗透课程】第四篇-Web安全之信息探测

    Web之信息探测,从这篇开始就正式进入了Web渗透实战过程了,嗯,前面都是讲基础,下面我们来讲Web中的信息探测. 信息探测,主要的目的 收集目标服务器系统信息(IP,服务器所用系统等) 收集目标网站 ...

  4. UEditor编辑器第一次赋值失败的解决方法

    网上查了很多方式都不是很好用,最后想到了这样的处理方式 首先在js中定义一个全局变量 var ue = null; 然后在初始化显示编辑器的时候js这样写 if (ue == null) { ue = ...

  5. 粗略使用.NetCore2.0自带授权登陆Authorize

    上篇有朋友提及到如果nginx做集群后应该还会有下一篇文章主讲session控制,一般来说就是登陆:本篇分享的内容不是关于分布式session内容,而是netcore自带的授权Authorize,Au ...

  6. 配置IIS使用Python

    打开IIS管理器 选择功能视图,然后选择ISAPI和CGI限制 打开后,在右侧操作,点击添加,会出现下图所示 按图中提示填写相应部分,在选择路径时,默认可能是dll文件,改成全部文件即可,然后再选择p ...

  7. javascript基础进阶——执行环境及作用域链

    概念 执行环境 执行环境定义了变量或函数有权访问的其他函数,决定了他们各自的行为.每个执行环境都有一个与之关联的变量对象. 变量对象 环境中定义的所有变量和函数都保存在这个对象中. 全局执行环境 全局 ...

  8. 【算法设计与分析基础】25、单起点最短路径的dijkstra算法

    首先看看这换个数据图 邻接矩阵 dijkstra算法的寻找最短路径的核心就是对于这个节点的数据结构的设计 1.节点中保存有已经加入最短路径的集合中到当前节点的最短路径的节点 2.从起点经过或者不经过 ...

  9. 使用 qemu 搭建内核开发环境

    本文主要介绍在 MacOS 上使用 qemu 搭建 Linux Kernel 的开发环境.(在开始之前需要注意的是,本文中的 Linux 开发环境是一个远程服务器,而 qemu 被安装在本地的 Mac ...

  10. Web in Linux小笔记001

    Linux灾难恢复: Root密码修复 Centos single Filesystem是硬盘文件根目录,无法再cd ..就像macitosh 硬盘图标 Pwd:显示绝对路径 MBR修复 模拟MBR被 ...