Map与Set
Symbol
ES5中基本数据:null undefined number boolean string
var a=new Number(200);//显示包装 var b=100; b.age=20;//new Number(100);隐式包装 console.log(b.age);//undefined //重新隐式包装 new Number(100)
Symbol是ES6新增基本数据。这是一个内置全局函数生成一个独一无二的数据。
//基本用法 let s1=Symbol(100); let s2=Symbol(100); console.log(s1==s2);//false //一般用途,命名时避免名字重复,避免改掉不想改的值 var obj={age:20}; function tool (obj) { let age=Symbol("年龄"); obj[age]=20; }
Map与Set
ES6新出的两个数据容器。
ES5的数据容器:数组、对象,作用:存取数据
//数组 var arr=[10,20]//new array(10,20)//初始化数据 arr.push(300)//添加数据 var b=arr[0]//取数据 arr.map(function(el){})//取数据 //对象 var obj = { age: 200, name: "karen" } //new Object() obj.life = 1 obj["age"] = 20
Map
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
var a=["key"] var m1=new Map([["age",10],[3,"hello"],[a,1]])//Map 初始化 //取数据 var re1=m1.get("age") var re2=m1.get(3) var re3=m1.get(["key"]) var re4=m1.get(a) console.log(re1,re2,re3,re4)//10 'hello' undefined 1 //存数据 m1.set("life",1) m1.set("age",1) console.log(m1) console.log(m1.size) //Map(4) {'age'=>1,3=>'hello',Array(1)=>1//['key']=>1,'life'=>1} //删除数据 m1.delete(3) var re5=m1.delete("age") var re6=m1.delete("age") console.log(m1,re5,re6)//Map(1) {Array(1)=>1} true false m1.clear() console.log(m1)//Map(0) {size: 0}
Map与object的区别
- 一个 Object 的键只能是字符串或者 Symbols,但一个 Map 的键可以是任意值。
- Map 中的键值是有序的(FIFO 原则),而添加到对象中的键则不是。
- Map 的键值对个数可以从 size 属性获取,而 Object 的键值对个数只能手动计算。
- Object 都有自己的原型,原型链上的键名有可能和你自己在对象上的设置的键名产生冲突。
Map中key
- key是字符串
var myMap = new Map(); var keyString = "a string"; myMap.set(keyString, "和键'a string'关联的值"); //注意 myMap.get(keyString); // "和键'a string'关联的值" myMap.get("a string"); // "和键'a string'关联的值" // 因为 keyString === 'a string'
- key是对象
var myMap = new Map(); var keyObj = {}, myMap.set(keyObj, "和键 keyObj 关联的值"); //注意 myMap.get(keyObj); // "和键 keyObj 关联的值" myMap.get({}); // undefined, 因为 keyObj !== {}
- key是函数
var myMap = new Map(); var keyFunc = function () {}, // 函数 myMap.set(keyFunc, "和键 keyFunc 关联的值"); //注意 myMap.get(keyFunc); // "和键 keyFunc 关联的值" myMap.get(function() {}) // undefined, 因为 keyFunc !== function () {}
- key是NaN
var myMap = new Map(); myMap.set(NaN, "not a number"); re1=myMap.get(NaN); // "not a number" var otherNaN = Number("foo"); re2=myMap.get(otherNaN); // "not a number" console.log(re1,re2,otherNaN)//not a number not a number NaN
Map特点:有序、键值对(键可以是任意类型)、键名不能重复(如果重复,那么覆盖)
Map的迭代:对Map进行遍历
- for...of
var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); //for...of遍历Map对象,取出每个键值对的键key和值value for (var [key, value] of myMap) { console.log(key + " = " + value); } //0 = zero //1 = one /* 这个 entries 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的 [key, value] 数组。 */ for (var [key, value] of myMap.entries()) { console.log(key + " = " + value); } //0 = zero //1 = one /* 这个 keys 方法返回一个新的 Iterator 对象, 它按插入顺序包含了 Map 对象中每个元素的键。 */ for (var key of myMap.keys()) { console.log(key); } //0 //1 /* 这个 values 方法返回一个新的 Iterator 对象,它按插入顺序包含了 Map 对象中每个元素的值。 */ for (var value of myMap.values()) { console.log(value); } //zero //one
- forEach()
var myMap = new Map(); myMap.set(0, "zero"); myMap.set(1, "one"); myMap.forEach(function(value, key) { console.log(key + " = " + value); }, myMap) //0 = zero //1 = one
Set
Set 对象允许你存储任何类型的唯一值,无论是原始值或者是对象引用。
Set 对象存储的值总是唯一的,所以需要判断两个值是否恒等。有几个特殊值需要特殊对待:
- +0 与 -0 在存储判断唯一性的时候是恒等的,所以不重复;
- undefined 与 undefined 是恒等的,所以不重复;
- NaN 与 NaN 是不恒等的,但是在 Set 中只能存一个,不重复。
var arr=[11,22,33,11] var s1=new Set(arr)//遍历的数组 然后把数组的元素们调用s1.add添加进集合中,去了重 s1.add(100) s1.add(100) s1.add(200) s1.add("hello") s1.add([100]) s1.add([100]) s1.add({age:1}) s1.add({age:1}) console.log(s1) //Set(10) //[[Entries]] //0: 11value: 11 //1: 22value: 22 //2: 33 //3: 100 //4: 200 //5: "hello" //6: Array(1)value: [100] //7: Array(1)value: [100] //8: Object value: {age:1} //9: Object value: {age:1} //size: 10 //[[Prototype]]: Set
Set对象作用
- 数组去重
var Set = new Set([1,1,2,2,3]) [...Set];//[1,2,3]
- 并集
var a = new Set([1, 2, 3]); var b = new Set([4, 3, 2]); var union = new Set([...a, ...b]); // {1, 2, 3, 4}
- 交集
var arr = [10, 20, 30, 10,{}] var arr2 = [100, 200,30,10] var s2 = new Set(arr.filter(function(el) { if (arr2.includes(el)) { return el } })) console.log(s2)//Set(2) {10, 30}
- 差集
var arr = [10, 20, 30, 10,{}] var arr2 = [100, 200,30,10] var s2 = new Set(arr.filter(function(el) { if (!arr2.includes(el)) { return el } })) console.log(s2)//Set(2) //20 Object
Map 与Array与Set与String的转换
var Array = [["key1", "value1"], ["key2", "value2"]]; //二维数组 // Map 构造函数可以将一个 二维 键值对数组转换成一个 Map 对象 //数组转Map,必须是二维数组 var myMap = new Map(kvArray); console.log(myMap); //Map(2) {"key1" => "value1", "key2" => "value2"} // 使用 Array.from 函数可以将一个 Map 对象转换成一个二维键值对数组 //Map转数组,使用Array from()静态方法 var Array1 = Array.from(myMap); console.log(Array1); //[["key1", "value1"], ["key2", "value2"]]
var arr=[100,200,100,{age:20},{age:20}] //数组转集合 var s1=new Set(arr) console.log(s1,s1.size)// //Set(4) 4 //0: 100 //1: 200 //2:value: {age: 20} //3:value: {age: 20} //集合转数组 var arr2=Array.from(s1) console.log(arr2,arr[4]==arr2[3]) //Array(4) true //0: 100 //1: 200 //2: {age: 20} //3: {age: 20}
//多个数组转集合和map: ... var arr1=[10,20] var arr2=[100,20] var arr3=[200,{name:"karen"}] var s1=new Set([...arr1,...arr2,arr3]) var m1=new Map([arr1,arr2,arr3]) var m2=new Map(m1) console.log(m1,m2,m1==m2,m1.get(200)==m2.get(200)) //Map(3) {10 => 20, 100 => 20, 200 => {name:"karen"}} Map(3) {10 => 20, 100 => 20, 200 => {name:"karen"}} false true //200 => {name:"karen"} 保存的是同一个对象 var mySet=new Set(" hel lo 华院\n") //两个空格算一个,\n算一个 console.log(mySet); //Set(8) {' ', 'h', 'e', 'l', 'o', '华', '院', ' '}