我们还是从一些现有的需求和问题出发,为什么会有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>
来源: http://www.cnblogs.com/ghostwu/p/7581922.html