ES6学习总结之Set和Map数据结构的理解

前言

当我们需要存储一些数据的时候,首先想到的是定义一个变量用来存储,之后我们可能学了数组,发现数组比变量可以存储更多的数据,接着可能有其它的存储数据的方法等等,然而我今天需要介绍的是在ES6中比较常见使用的数据类型结构,Set和Map。

Set数据结构

1.Set简介

  • set中成员的值都是唯一的,没有重复的值

  • 向set中添加成员时,不会发生类型转换

  • 向set中添加的对象总是不想等

2.常用的属性和方法

  • size:返回set实例的成员总数

  • add():添加某个值,返回set本身

  • delete():删除某个值,返回一个布尔值,判断删除是否成功

  • has():返回一个布尔值,表示该值是否为set成员

  • clear():清除所有成员,没有返回值

  • keys():返回键名的遍历器

  • values():返回键值的遍历器

  • entries():返回键值对的遍历器

  • forEach():使用回调函数遍历每个成员

3.实例剖析

为了方便大家更好的了解和学习set,我在这里会将这些方法和属性进行分类整理和讲解

1.set的基本用法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>数组去重</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();    //创建set数据结构
            [1,1,2,3,4,5].forEach(x=>{
                set.add(x);
            })
            console.log(set);    //1,2,3,4,5
            for(let i of set){
                console.log(i);
            }
        </script>
    </body>
</html>

可以看到向Set添加成员时,不会添加重复的值

2.数组作为参数传入到set结构中

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title></title>
    </head>
    <body>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <div></div>
        <script type="text/javascript">
//            const set=new Set([1,2,3]);
//            console.log(...set);//1,2,3,使用扩展运算符

            const set=new Set(document.querySelectorAll(‘div‘));
            console.log(set.size);//5 size返回set实例的成员总数
            //如上代码相当于
            const item=new Set();
            document.querySelectorAll(‘div‘).forEach(x=>{
                item.add(x);
            })
            console.log(item);
            console.log(item.size);//5
        </script>
    </body>
</html>

3.set中添加的值不会发生类型转换

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>向set中添加成员时,不会发生类型转换</title>
    </head>
    <body>
        <script type="text/javascript">
            let mySet=new Set();
            mySet.add(5);
            mySet.add(‘5‘);
            console.log(mySet);//5,‘5‘
            let set=new Set();
            let a=NaN;
            let b=NaN;
            set.add(a);
            set.add(b);
            console.log(set);//NaN
        </script>
    </body>
</html>

向 Set 加入值的时候,不会发生类型转换,所以5"5"是两个不同的值。Set 内部判断两个值是否不同,使用的算法叫做“Same-value-zero equality”,它类似于精确相等运算符(===),主要的区别是向 Set 加入值时认为NaN等于自身,而精确相等运算符认为NaN不等于自身。

4.set中添加的对象总是不想等的

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>向set中添加的对象总是不想等</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set();
            set.add({});//向set中添加一个空对象
            console.log(set.size);//1
            set.add({});//向set中添加另一个空对象
            console.log(set.size);//2
        </script>
    </body>
</html>

由于两个空对象不行等,所以它们被视为两个值

4.set实例属性和方法

(1):size属性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的size属性</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();
            //向set中添加成员
            set.add(1);
            set.add(2);
            set.add(3);
            //链式方法
            set.add(4).add(5).add(6);
            console.log(set.size);//6
        </script>
    </body>
</html>

(2):操作方法add()、delete()、has()、clear()

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的操作方法add()、delete()、has()、clear()</title>
    </head>
    <body>
        <script type="text/javascript">
            const set=new Set();
            //向set中添加成员
            set.add(1);
            set.add(2);
            set.add(3);
            //链式方法
            set.add(4).add(5).add(6);
            console.log(set.size);//6
            console.log(set.has(1));//true
            set.delete(1);
            console.log(set.has(1));//false
            set.clear();//清空全部set成员
            console.log(set.size);//0
        </script>
    </body>
</html>

(3):遍历方法keys()、values()、entries()、forEach()

注意:set的遍历顺序就是插入顺序,由于set没有键名,只有键值(或者说键名和键值是同一个值),所以keys()和values()方法的行为完全一致

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>set中的遍历方法keys(),values(),entries(),forEach()</title>
    </head>
    <body>
        <script type="text/javascript">
            let set=new Set([‘red‘,‘blue‘,‘green‘]);
            //遍历全部的key
            for(let key of set.keys()){
                console.log(key);//red,blue,green
            }
            //遍历全部的value
            for(let value of set.values()){
                console.log(value);//red,blue,green
            }
            //遍历全部的key和value
            for(let item of set.entries()){
                console.log(item);//[‘red‘,‘red‘],[‘blue‘,‘blue‘],[‘green‘,‘green‘]
            }
            set.forEach((key,value)=>{
                console.log(key+‘:‘+value);
            })
        </script>
    </body>
</html>

Map数据结构

1.Map简介

es6中的map很大程度上和set相似,但是map是以键值对的形式存储数据的

2.常用的属性和方法

  • size:返回map结构的成员总数

  • set(key,value):设置键名key对应的键值value,然后返回整个map结构,如果key已经有值,则键值会被更新,否则就新生成该键

  • get(key):读取key对应的键值,如果找不到key,则返回undefined

  • has(key):返回一个布尔值,表示某个键是否在当前map对象中

  • delete(key):删除某个key,返回true,如果删除失败,返回false

  • clear():清除所有成员,没有返回值

  • keys():返回键名的遍历器

  • values():返回键值的遍历器

  • entries():返回键值对的遍历器

  • forEach():遍历map的所有成员

3.实例剖析

(1):size属性

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的size属性</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set(‘foo‘,true);
            map.set(‘bar‘,false);
            console.log(map.size);//2
        </script>
    </body>
</html>

(2):set(key,value)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的set()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set(‘1‘,‘a‘);//键是字符串
            map.set(2,‘b‘);//键是数值
            map.set(undefined,‘3‘);//键是undefined
            console.log(map);//‘1‘=>a,2=>b,undefinde=3
            const myMap=new Map();
            //链式写法
            myMap.set(1,‘a‘).set(2,‘b‘).set(3,‘c‘);
            console.log(myMap);//1=>a,2=>b,3=>c
        </script>
    </body>
</html>

(3):get(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的get()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            const hello=function(){
                console.log(‘你好‘);
            }
            map.set(hello,‘es6‘);//键是函数
            console.log(map.get(hello));//es6
        </script>
    </body>
</html>

(4):has(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的has()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            //链式写法
            map.set(‘a‘,1).set(‘b‘,2).set(‘c‘,3);//向map中添加成员
            console.log(map.has(‘a‘));//true
            console.log(map.has(‘b‘));//true
            console.log(map.has(‘c‘));//true
            console.log(map.has(‘d‘));//false
        </script>
    </body>
</html>

(5):delete(key)方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的delete方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set(‘a‘,1);
            console.log(map.has(‘a‘));//true
            map.delete(‘a‘);//删除键a
            console.log(map.has(‘a‘));//false
        </script>
    </body>
</html>

(6):clear()方法

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map中的clear()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            map.set(‘foo‘,true);//向map中添加成员
            map.set(‘bar‘,false);
            console.log(map.size);//2
            map.clear();//清除map中的全部成员
            console.log(map.size);//0
        </script>
    </body>
</html>

(7):遍历方法keys()、values()、entries()、forEach()

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>遍历方法keys(),values(),entries(),forEach()</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();
            //向map中添加成员
            map.set(1,‘a‘);
            map.set(2,‘b‘);
            map.set(3,‘c‘);
            //遍历全部的键
            for(let key of map.keys()){
                console.log(key);//1,2,3
            }
            //遍历全部的值
            for(let values of map.values()){
                console.log(values);//a,b,c
            }
            //遍历全部的键和值
            for(let [key,value] of map.entries()){
                console.log(key,value);//1=>a,2=>b,3=>c
            }
            for(let item of map.entries()){
                console.log(item[0],item[1]);//1=>a,2=>b,3=>c
            }
            for(let [key,value] of map){
                console.log(key,value);//1=>a,2=>b,3=>c
            }
            map.forEach(function(value,key){
                console.log(key,value);
            })
        </script>
    </body>
</html>

注意:这里的forEach()是值在前,键在后

(8):map结构转为数组

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map结构转为数组</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map([
                [1,‘one‘],
                [2,‘two‘],
                [3,‘three‘]
            ]);
            console.log([...map.keys()]);//[1,2,3]
            console.log([...map.values()]);//one,two,three
            console.log([...map]);//[1,one],[2,two],[3,three]
            console.log([...map.entries()]);//[1,one],[2,two],[3,three]
            const map1=new Map(
                [...map].filter(([key,value])=>key<3)//使用数组的filter方法
            );
            console.log(map1);//1=>one,2=>two
        </script>
    </body>
</html>

4.Map与其它数据结构的转换

作为键值对存储数据的map与其它数据也可以进行转换,我们看下下面的案例

(1)Map转为数组

map转为数组最方便的方法,就是使用扩展运算符...

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>Map转为数组</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map();//创建map数据结构
            map.set(true,7);//向map中添加成员
            map.set({foo:3},[‘abc‘]);
            console.log([...map]);//[[true,7],[{foo:3},[‘abc‘]]];
        </script>
    </body>
</html>

(2)数组转为Map

将数组传入map构造函数,就可以转为map

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>数组转为map</title>
    </head>
    <body>
        <script type="text/javascript">
            const map=new Map([
                [true,7],
                [{foo:3},[‘abc‘]]
            ]);
            console.log(map);
            //map{
                //true=>7,
                //object:{foo:3}=>[‘abc‘];
            //}
        </script>
    </body>
</html>

(3)Map转为对象

如果所有map的键都是字符串,它可以无损的转为对象,如果有非字符串的键名,那么这个键名会被转为字符串,再作为对象的键名

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map转为对象</title>
    </head>
    <body>
        <script type="text/javascript">
            function strMapObj(strMap){
                let obj=Object.create(null);//创建一个新对象
                for(let [key,value] of strMap){//遍历循环strMap
                    obj[key]=value;
                }
                return obj;
            }
            const map=new Map().set(‘yes‘,true).set(‘no‘,false);
            console.log(strMapObj(map));//{yes:true,no:false}
        </script>
    </body>
</html>

在这里了我需要讲解一下Object.create()这个方法,官方的意思是:Object.create()方法创建一个新对象,使用现有的对象来提供新创建的对象的__proto__

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>测试Object.create()方法</title>
    </head>
    <body>
        <script type="text/javascript">
            const person={
                isHuman: false,
                  printIntroduction: function () {
                    console.log(this.name,this.isHuman);
                  }
            }
            const me = Object.create(person);
            me.name = "Matthew";
            me.isHuman = true;
            me.printIntroduction();//Mattew,true
        </script>
    </body>
</html>

(4)对象转为Map

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>对象转为map</title>
    </head>
    <body>
        <script type="text/javascript">
            function objToMap(obj){
                let map=new Map();
                for(let key of Object.keys(obj)){
                    map.set(key,obj[key]);
                }
                return map;
            }
            console.log(objToMap({yes:true,no:false}));//yes=>true,no=>false
        </script>
    </body>
</html>

在这里讲解Object.keys()方法,官方解释:Object.keys() 方法会返回一个由一个给定对象的自身可枚举属性组成的数组,数组中属性名的排列顺序和使用,for..in循环遍历该对象时返回的顺序一致 。如果对象的键-值都不可枚举,那么将返回由键组成的数组。

参数:要返回其枚举自身属性的对象

返回值:一个表示给定对象的所有可枚举属性的字符串数组

// simple array
var arr = [‘a‘, ‘b‘, ‘c‘];
console.log(Object.keys(arr)); // console: [‘0‘, ‘1‘, ‘2‘]

// array like object
var obj = { 0: ‘a‘, 1: ‘b‘, 2: ‘c‘ };
console.log(Object.keys(obj)); // console: [‘0‘, ‘1‘, ‘2‘]

// array like object with random key ordering
var anObj = { 100: ‘a‘, 2: ‘b‘, 7: ‘c‘ };
console.log(Object.keys(anObj)); // console: [‘2‘, ‘7‘, ‘100‘]

// getFoo is a property which isn‘t enumerable
var myObj = Object.create({}, {
  getFoo: {
    value: function () { return this.foo; }
  }
});
myObj.foo = 1;
console.log(Object.keys(myObj)); // console: [‘foo‘]

(5)Map转为JSON字符串

map转为json要区分两种情况,一种情况时map的键名都是字符串,这时可以选择转为对象json,另一种情况是map的键名有非字符串,这时可以选择转为数组json。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>map转为json</title>
    </head>
    <body>
        <script type="text/javascript">
            function strMapToObj(strMap){
                let obj=Object.create(null);//创建一个新对象
                for(let [key,value] of strMap){
                    obj[key]=value;
                }
                return obj;
            }
            function strMapToJson(strMap){
                return JSON.stringify(strMapToObj(strMap));
            }
            let map=new Map().set(‘yes‘,true).set(‘no‘,false);
            let obj=strMapToJson(map);
            console.log(obj);//{‘yes‘:true,‘no‘:false}
            function mapToArrayJson(map){
                return JSON.stringify([...map]);
            }
            let fooMap=new Map().set(true,7).set({foo:3},[‘abc‘]);
            let foo=mapToArrayJson(fooMap);
            console.log(foo);//[[true:7],[{foo:3},[‘abc‘]]]
        </script>
    </body>
</html>

(6)JSON字符串转为Map

json转为map,正常情况下所有键名都是字符串,但是有一种特殊情况,整个json就是一个数组,且每个数组成员本身,又是一个有两个成员的数组,这时它可以一一对应的转为map,这往往是map转为数组json的逆操作。

<!DOCTYPE html>
<html>
    <head>
        <meta charset="UTF-8">
        <title>json转为map</title>
    </head>
    <body>
        <script type="text/javascript">
            function objTostrMap(obj){
                let map=new Map();
                for(let key of Object.keys(obj)){
                    map.set(key,obj[key]);
                }
                return map;
            }
            function jsonToStrMap(jsonStr){
                return objTostrMap(JSON.parse(jsonStr));
            }
            let obj1=jsonToStrMap(‘{"yes": true, "no": false}‘)
            console.log(obj1);//yes=>true,no=>false
            function jsonToMap(jsonStr){
                return new Map(JSON.parse(jsonStr));
            }
            let obj2=jsonToMap(‘[[true,7],[{"foo":3},["abc"]]]‘)//true=>7,{foo:3}=>[‘abc‘]
            console.log(obj2);
        </script>
    </body>
</html>

参考资料:http://es6.ruanyifeng.com/#docs/set-map

总结

本章我们主要学习了ES6中set和map相关的属性和方法,set和map的方法中有很多都是相同的方法,has()、delete()、clear()、keys()、values()、entries、forEach()等等。

原文地址:https://www.cnblogs.com/jjgw/p/11561169.html

时间: 2024-08-29 17:37:37

ES6学习总结之Set和Map数据结构的理解的相关文章

ES6学习小结6:何为Map?

什么是map?类似于对象的数据结构,成员键可以是任何类型的值. 具体化:我们知道原先对象内属性名只能是字符串,而Map属性名可以是字符串,也可以是对象或数组.它是一个更完善的hash结构. 属性: 方法: 补充说明: 1.遍历顺序:插入顺序 2.对同一个键多次赋值,后面的值将覆盖前面的值 3.对同一个对象的引用,被视为一个键 4.对同样值的两个实例,被视为两个键 5.键跟内存地址绑定,只要内存地址不一样就视为两个键 6.添加多个以NaN作为键时,只会存在一个以NaN作为键的值 7.Object结

ES6(九)set、map数据结构

Set 元素不会重复 let list = new Set() list.add(5) list.add(7) console.log(list) // 长度 console.log(list.size) let arr = [1, 2, 3, 4, 5] let list = new Set(arr) console.log(list) 去重 let arr = [1, 2, 3, 4, 2, 3, 4, 3, 4] let list = new Set(arr) console.log(li

js ES6 Set和Map数据结构详解

这篇文章主要介绍了ES6学习笔记之Set和Map数据结构,结合实例形式详细分析了ECMAScript中基本数据结构Set和Map的常用属性与方法的功能.用法及相关注意事项,需要的朋友可以参考下 本文实例讲述了ES6学习笔记之Set和Map数据结构.分享给大家供大家参考,具体如下: 一.Set ES6提供了新的数据结构Set.类似于数组,只不过其成员值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. 1 . Set函数可以接受一个数组(或类似数组的对象)作为参数,用来

ES6中map数据结构学习

在项目中遇到一个很恶心的需求,然后发现ES6中的map可以解决,所以简单学习了一下map. Javascript的Object本身就是键值对的数据结构,但实际上属性和值构成的是“字符串-值”对,属性只能是字符串,如果传个对象字面量作为属性名,那么会默认把对象转换成字符串,结果这个属性名就变成“[object Object]”:. ES6提供了“值-值”对的数据结构,键名不仅可以是字符串,也可以是对象.它是一个更完善的Hash结构. 1.键值对,键可以是对象 const map1 = new Ma

ES6学习之Set 和 Map 数据结构

Set对象 ES6 提供了新的数据结构 Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set 实例的属性和方法 Set.prototype.constructor:构造函数,默认就是Set函数. Set.prototype.size:返回Set实例的成员总数 Set.prototype.add(value):添加某个值,返回 Set 结构本身. Set.prototype.delete(value):删除某个值,返回一个布尔值,表示删除是否成功. Set.prototype.ha

了解ES6的Map数据结构

<script> /* Map数据结构是ES6推出的,它是一个类对象,普通对象的键值只能使用string,而map数据结构的键值可以使用任意对象,不受限制 Map是一个构造函数,通过new Map() 来构建 如果需要键值对的数据格式,Map比Object更加适合 如果对同一个键进行重复赋值,那么前面的值会被后替换 拥有于set数据结构同样的遍历方法,遍历的顺序就是数据插入的顺序 转化为数组结构可以使用展开运算符 ... */ let map = new Map([ [{a:'a'},123]

ES6中的Set、Map数据结构

Map.Set都是ES6新的数据结构,他们都是新的内置构造函数.也就是说typeof的结果,多了两个. 他们是什么:  Set是不能重复的数组.    Map是可以任何东西当做键的对象: ES6 提供了新的数据结构 Set.它类似于数组,但是Set成员的值都是唯一的,没有重复的值. let m = new Set(); m.add(1); m.add(2); m.add(3); m.add(3); m.add(3); m.add(4); m.add(5); console.log(m); 集合中

ES6 之 Set数据结构和Map数据结构 Iterator和for...of循环

ECMAScript 6 入门 Set数据结构 基本用法 ES6提供了新的数据结构Set.它类似于数组,但是成员的值都是唯一的,没有重复的值. Set本身是一个构造函数,用来生成Set数据结构. var s = new Set(); [2, 3, 5, 4, 5, 2, 2].map(x => s.add(x)); for (let i of s) { console.log(i); } // 2 3 5 4 上面代码通过add方法向Set结构加入成员,结果表明Set结构不会添加重复的值. 向S

sizzle.js学习笔记利用闭包模拟实现数据结构:字典(Map)

sizzle.js学习笔记利用闭包模拟实现数据结构:字典(Map) 这几天学习和查看了jQuery和Property这两个很流行的前端库的御用选择器组件Sizzle.js的源代码,收获还是相对多的!之前一直做使用Java语言开发,其丰富的组件类库使得开发效率那叫一个快呀!突然转来做JavaScript一时间还有点儿不适应(快半年了),不过自从看见那么多漂亮的网站和对JavaScript接触的越来越多,也发现了其中的一些乐趣.正如自己一直坚信的那样,编程语言仅仅是工具,重要的是编程思想!使用Jav