[js高手之路] es6系列教程 - Set详解与抽奖程序应用实战

时间:2022-07-29 23:58:26

我们还是从一些现有的需求和问题出发,为什么会有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. &lbrack;js高手之路&rsqb; es6系列教程 - Map详解以及常用api

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

  2. &lbrack;js高手之路&rsqb; es6系列教程 - 对象功能扩展详解

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

  3. &lbrack;js高手之路&rsqb; es6系列教程 - 迭代器&comma;生成器&comma;for&period;&period;&period;of&comma;entries&comma;values&comma;keys等详解

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

  4. &lbrack;js高手之路&rsqb; es6系列教程 - 迭代器与生成器详解

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

  5. &lbrack;js高手之路&rsqb; es6系列教程 - promise常见用法详解&lpar;resolve&comma;reject&comma;catch&comma;then&comma;all&comma;race&rpar;

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

  6. &lbrack;js高手之路&rsqb; es6系列教程 - 函数的默认参数详解

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

  7. &lbrack;js高手之路&rsqb; es6系列教程 - 箭头函数详解

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

  8. &lbrack;js高手之路&rsqb; es6系列教程 - var&comma; let&comma; const详解

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

  9. &lbrack;js高手之路&rsqb; es6系列教程 - 不定参数与展开运算符&lpar;&period;&period;&period;&rpar;

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

随机推荐

  1. Java设计模式(一) 策略模式

    策略模式:定义了算法族,分别封装起来,让它们之间可以互相替换,此模式让算法的变化独立于使用算法的客户. 1,定义算法接口 package com.pattern.strategy.test; publ ...

  2. 每天一个脚本解析day1&equals;&equals;》《service xxxxx status》之service脚本解析

    vim    /sbin/service #!/bin/sh . /etc/init.d/functions #读取环境变量. VERSION="$(basename $0) ver. 0. ...

  3. PHP正则表达式匹配中文字符

    网上有很多类似的文章,但往往都不能用 所以记录一下 preg_match_all("/([\x{4e00}-\x{9fa5}])/u", $input, $match); 注意:限 ...

  4. C51变量的存储

    一.全局变量和局部变量 全局变量和局部变量的区别在于作用域的不同.此外还有静态全局变量和静态局部变量. 全局变量作用域为全局,在一个源文件中定义,其他的源文件也可以应用.在其他的源文件中使用exter ...

  5. red hat Linux 使用CentOS yum源更新

    red hat linux是商业版软件,没有经过注册是无法使用红帽 yum源更新软件的,使用CentOS源更新操作如下: 1.删除red hat linux 原有的yum 源 rpm -aq | gr ...

  6. &lbrack;进程管理&rsqb; 理解 Linux 的处理器负载均值

    原文链接: http://blog.scoutapp.com/articles/2009/07/31/understanding-load-averages http://www.gracecode. ...

  7. C&num;基础知识-流程控制的应用(四)

    流程控制我们在编程中运用到的地方非常的多,在上篇中仅仅只是简单的介绍每一种的使用,并没有运用到实例中,很难去理解它真正的作用.下面我们将实际的运用流程控制的代码写一些实例相关的程序,加深对流程控制的理 ...

  8. 代码生成利器:IDEA 强大的 Live Templates&lpar;转&rpar;

    代码生成利器:IDEA 强大的 Live Templates - 文章 - 伯乐在线http://blog.jobbole.com/110607/ 前言 Java 开发过程经常需要编写有固定格式的代码 ...

  9. VMware中的桥接模式、NAT&lpar;网络地址转换模式&rpar;、Host-only&lpar;主机模式&rpar;:转自:http&colon;&sol;&sol;blog&period;chinaunix&period;net&sol;uid-11798538-id-3061551&period;html

    其中VMnet1是虚拟机Host-only模式的网络接口,VMnet8是NAT模式的网络接口,这些后面会详细介绍.在个虚拟交换机,分别是-个虚拟机交换机,而在VMware Workstation 5以 ...

  10. CImage 对话框初始化时候显示透明 PNG

    使用CImage的时候,发现显示出来的并不是透明背景的图片,而是白色背景的图片. 后发现原因如下: PNG图片的透明背景总是一片白色,后来才发现这其实是微软GDI+的设计问题,PNG图片是ARGB,使 ...