JavaScript中对象的本质是键值对的集合,ES5中的数据结构,主要是用Array和Object,可是键只能是字符串。为了弥补这种缺憾,ES6带来了一种新的数据结构Map。数组
Map也是键值对的集合,只是键不只能够是字符串还能够是其余数据类型,好比:对象(是否是很神奇)。请看下面例子。。下面话很少说了,来一块儿看看详细的介绍吧。数据结构
Map结构提供了“值—值”的对应,任何值(对象或者原始值) 均可以做为一个键或一个值,是一种更完善的Hash结构实现。若是你须要“键值对”的数据结构,Map比Object更合适。它相似于对象,也是键值对的集合,可是“键”的范围不限于字符串,各类类型的值(包括对象)均可以看成键。函数
Map属性this
Map.length 属性length的值为0。spa
Map.prototype 表示Map构造器的原型。容许添加属性从而应用与全部的Map对象.net
Map实例 - 全部Map对象的实例都会继承Map.prototype。prototype
Map.prototype.constructor 返回建立给map实例的构造函数,默认是Map函数。code
Map.prototype.size 返回Map对象的键值对的数量。对象
var map = new Map([['one',1], ['two', 2], ['three', 3]]); console.log(map.constructor); //function Map() { [native code] } console.log(map.size); //3
//Iterator对象:可使用for..of进行迭代的对象 var map = new Map([[1, 'one'],[2, 'two'], [3, 'three']]);
1.Map.prototype.set(key, value) 设置Map对象中键的值,返回该Map对象。blog
console.log(map.has(4)); //false map.set(4, 'four'); console.log(map.has(4)) //true
2.Map.prototype.get(key) 返回键对应的值,若是不存在,则返回undefined。
map.get(1); //'one'
3.Map.prototype.has(key) 返回一个布尔值,表示Map实例是否包含键对应的值。
map.has(1); // true map.has(5); //false
4.Map.prototype.delete(key) 移除任何与键相关联的值,而且返回该值,该值在以前会被Map.prototype.has(key)返回为true。以后再调用则返回false。
console.log(map.has(1)); //true map.delete(1); console.log(map.has(1)); //false
5.Map.prototype.clear() 移除Map对象的全部键值对。
console.log(map.size); //3 map.clear(); console.log(map.size); //0
6.Map.prototype.entries() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每一个元素的[key, value]数组。
console.log(map); //Map {1 => "one", 2 => "two", 3 => "three"} map.entries(); console.log(map); //Map {1 => "one", 2 => "two", 3 => "three"}
7.Map.prototype.forEach(callbackFn[, thisArg]) 按插入顺序,为Map对象里的每一键值对调用一次callbackFn函数。若是为forEach提供了thisArg,他将在每次回调函数中做为this值。
map.forEach(function(value, key, mapObj) { console.log(value + '---' + key + '---' + mapObj); //value - Map对象里每个键值对的值 //key - Map对象里每个键值对的键 //mapObj - Map对象自己 console.log(this); //this === window }); map.forEach(function(value, key, mapObj) { console.log(value + '---' + key + '---' + mapObj); console.log(this); //this === map }, map)
8.Map.prototype.keys() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每一个元素的键。
map.keys(); //MapIterator {1, 2, 3}
9.Map.prototype.values() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每一个元素的值。
map.values(); //
var map = new Map(); map.set(1, 'one'); map.set(2, 'two'); for (var [key, value] of map) { console.log(key + '---' + value); } // 1 --- one 2 --- two for (var key of map.keys()) { console.log(key); } // 1 2 for (var value of map.values()) { console.log(value); } // 'one' 'two'
var map = new Map(); //建立map对象 map.set('one', 1); map.set('two', 2); map.set('three', 3); //或者 var map = new Map([['one',1], ['two', 2], ['three', 3]]); m.set(ul,'content'); //为Map增长成员 m.get(ul);//获取键 ul对应的值 m.has(ul);//返回布尔值,判断是否含有键 ul m.delete(ul);//删除键 ul,成功返回true,失败返回false m.size //返回m长度 m.clear(); //清除m全部成员
一个对象一般都有本身的原型,因此一个对象总有一个"prototype"键。不过,从ES5开始可使用map = Object.create(null)来建立一个没有原型的对象。
一个对象的键只能是字符串或者Symbols,但一个Map的键能够是任意值。
你能够经过size属性很容易地获得一个Map的键值对个数,而对象的键值对个数只能手动确认。
扩展语法容许一个表达式在指望多个参数(用于函数调用)或多个元素(用于数组字面量)或多个变量(用于解构赋值)的位置扩展。
let arr1 = [0, 1, 2]; let arr2 = [3, 4, 5]; arr1 = [...arr2, ...arr1]; console.log(arr1) // [3, 4, 5, 0, 1, 2]
Map转数据的最简单方式是使用 ... 扩展运算符。例如:
var map = new Map([['one',1], ['two', 2], ['three', 3]]); console.log(...map); //["one", 1] ["two", 2] ["three", 3]
Map转对象时,必须全部键都是字符串,使用Object.create()函数。Map转JSON时,要求也要求全部键都是字符串,使用JSON.Stringify()函数。
一、转换时注意
二、当键是对象时,必须是引用相同,才认为键是相同的。只有对同一个对象的引用,Map结构才将其视为同一个键。这一点要很是当心。
var map = new Map(); map.set(['a'], 555); map.get(['a']) // undefined //上面代码的set和get方法,表面是针对同一个键,但实际上这是两个值,内存地址是不同的,所以get方法没法读取该键,返回undefined。
三、若是Map的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map将其视为一个键,包括0和-0。另外,虽然NaN不严格相等于自身,但Map将其视为同一个键。
var map = new Map(); map.set(Number('aa111'), 'isNaN'); map.set(Number('bb222'), 'also is NaN'); map.get(NaN); //'also is NaN'
四、注意区分Map对象与JavaScript Array map() 方法
Array map() 语法 array.map(function(currentValue,index,arr), thisValue) 实例1 //返回一个数组,数组中元素为原始数组的平方根: var numbers = [4, 9, 16, 25]; function myFunction() { x = document.getElementById("demo") x.innerHTML = numbers.map(Math.sqrt); } //2,3,4,5 实例2 //数值项求平方: var data = [1, 2, 3, 4]; var arrayOfSquares = data.map(function (item) { return item * item; }); alert(arrayOfSquares); // 1, 4, 9, 16
ES6提供了新的数据结构Set。它相似于数组,可是成员的值都是惟一的,没有重复的值。
Set函数能够接受一个数组(或相似数组的对象)做为参数,用来初始化。
Set对象容许你存储任意类型的惟一值(不能重复),不管它是原始值或者是对象引用。
Set自己是一个构造函数,用来生成Set数据结构。
Set结构有如下属性:
Set结构有如下方法:
Set遍历操做:
Set.length 属性length的值为0。
Set.prototype 表示Set构造器的原型。容许向全部Set对象添加新的属性。
Set.prototype.constructor 返回建立给set实例的构造函数,默认是Set函数。
Set.prototype.size 返回Set对象的键值对的数量。
var sset = new Set(['one', 'two', 'three']); console.log(sset.constructor); //function Set() { [native code] } console.log(sset.size); //3
//建立Set实例
//1.
var sset = new Set();
sset.add('one');
sset.add('two');
sset.add('three');
//2.
var sset= new Set(['one', 'two', 'three']);
1.Set.prototype.add(value) 在Set对象尾部添加一个元素。返回该Set对象。
sset.add('four'); console.log(sset); //Set {"one", "two", "three", "four"}
2.Set.prototype.clear() 移除Set对象内的全部元素。
sset.clear(); console.log(sset.size); //0
3.Set.prototype.delete(value) 移除Set的中与这个值相等的元素,返回Set.prototype.has(value)在这个操做前会返回的值(即若是该元素存在,返回true,不然返回false)。Set.prototype.has(value)在此后会返回false。
console.log(sset.has('one')); //true sset.delete('one'); console.log(sset.has('one')); //false
4.Set.prototype.entries() 返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的全部元素的值的[value, value]数组。为了使这个方法和Map对象保持类似, 每一个值的键和值相等。
5.Set.prototype.forEach(callbackFn[, thisArg]) 按照插入顺序,为Set对象中的每个值调用一次callBackFn。若是提供了thisArg参数,回调中的this会是这个参数。
sset.forEach(function(value, key, setObj) { console.log(value + '---' + key + '---' + setObj); //value - Set对象里每个键值对的值 //key - Set对象里每个键值对的键 === 值 //mapObj - Set对象自己 console.log(this); //this === window }); sset.forEach(function(value, key, setObj) { console.log(value + '---' + key + '---' + setObj); console.log(this); //this === sset }, sset)
6.Set.prototype.has(value) 返回一个布尔值,表示Map实例是否包含键对应的值。
sset.has('one'); // true sset.has('fivr'); //false
7.Set.prototype.keys() 与values()方法相同,返回一个新的迭代器对象,该对象包含Set对象中的按插入顺序排列的全部元素的值。
sset.keys(); //SetIterator {"one", "two", "three"}
8.Set.prototype.values() 返回一个新的Iterator对象,它按插入顺序包含了Map对象中每一个元素的值。
sset.values(); //SetIterator {"one", "two", "three"}
var sset = new Set(); sset.add(1); sset.add(2); for (var value of sset) { console.log(value); } // 1 2 for (var key of sset.keys()) { console.log(key); } // 1 2 for (var value of sset.values()) { console.log(value); } // 1 2
var myArray = ["value1", "value2", "value3"]; // 用Set构造器将Array转换为Set var mySet = new Set(myArray); mySet.has("value1"); // returns true // 用...(展开操做符)操做符将Set转换为Array console.log([...mySet]); // 与myArray彻底一致
Array.from方法能够将Set结构转换为数组。
var items = new Set([1, 2, 3, 4, 5]); var array = Array.from( items );
这也提供了一种除去数组中重复元素的方法。
function dedupe( array ) { return Array.from( new Set(array) ); }
或者以下写也能够,比较简单的数组去重
[...new Set([1,3,4,5,1,2,3,3,4,8,90,3,0,5,4,0])]
一、var sset = new Set('one', 'two', 'three'); //这样的错误的
二、值的相等规则:NaN 是与NaN是相同的(虽然NaN !== NaN),除此以外全部的值都根据'==='判断。
var sset= new Set(); sset.add(Number('aa111')); sset.add(Number('bb222')); sset.add('cc333')); //Set {NaN, "cc333"}
三、向Set加入值的时候,不会发生类型转换。这意味着,在Set中5和”5”是两个不一样的值。
WeakSet结构与Set相似,也是不重复的值的集合。
WeakSet和Set的区别:
WeakSet结构的三个方法adddeletehasWeakSet的一个用处是储存DOM节点,而不用担忧这些节点会从文档中移除时,会引起内存泄露。