您的位置:首页 > Web前端 > JavaScript

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

2017-09-23 17:52 931 查看
我们还是从一些现有的需求和问题出发,为什么会有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 ); //2


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 ); //2


因为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 ); // 1

set.clear();
console.log( set.has( 5 ) ); // false
console.log( set.size ); // 0


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

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


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>
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: