ES6新增的集合类型(引用数据类型),表示数据的映射关系
,map集合数据类型中数据是以键/值
的方式存储的.可以使用对象的属性作为键,使用属性来引用值。
使用new
关键字来实例一个map
let m = new Map();
console.log(m);
// Map(0) {}
创建时初始化:
传入一个二维数组参数(可迭代对象,内部以数组的方式传入键值)
每个子数组,第一个元素是map对应的key
, 第二个元素是map对应的value
let m = new Map([[{}, 222], [{}, '123']]);
console.log(m);
// Map(2) { {} => 222, {} => '123' }
通过set()方法添加,传入两个参数,第一个传入映射的键,第二个传入映射的值。返回的是该映射集合(意味着可以链式添加)
let m = new Map();
m.set('prop', '值');
console.log(m);
// Map(1) { 'prop' => '值' }
链式添加键值
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
console.log(m);
// Map(3) { 'prop' => '值', 'prop2' => false, 'num' => { id: 13 } }
使用size
属性可以获取到当前集合元素数量
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
console.log(m.size);
通过get()方法获取到元素,传入获取目标的key
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
console.log(m.get('prop2'));
// false
通过delete()方法删除映射集合中的某个元素,返回删除成功或失败的布尔值
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
m.delete('prop2');
// true
console.log(m.get('prop2'), m.size);
// undefined 2
使用has()方法检测目标元素是否存在,返回检测结果的布尔值
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
m.delete('prop2');
// true
console.log(m.has('prop2'), m.has('num'));
// false true
使用clear()方法可以清除所有的元素, 返回清除成功的布尔值
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
m.clear();
// true
console.log(m);
// Map(0) {}
map可以根据插入顺序迭代元素
映射实例会提供(iterator).能够以插入的顺序生成[key, value]形式的数组, 可以通过entries()方法(或者提供的Symbol.iterator)迭代器接口遍历。
let m = new Map();
m.set('prop', '值').set('prop2', false).set('num', {id: 13});
console.log(m.entries === m[Symbol.iterator]);// true
for(let k1 of m.entries()){
console.log(k1);
// [ 'prop', '值' ]
// [ 'prop2', false ]
// [ 'num', { id: 13 } ]
// 遍历的属性即对应映射元素的键值对数组
}
for(let k2 of m.keys()){
console.log(k2);
// prop
// prop2
// num
// 遍历的属性对应映射元素的键
}
for(let k3 of m.values()){
console.log(k3);
// 值
// false
// { id: 13 }
// 遍历的属性对应映射元素的值
}
for(let k4 of m[Symbol.iterator]()){
console.log(k4);
// [ 'prop', '值' ]
// [ 'prop2', false ]
// [ 'num', { id: 13 } ]
// 遍历的属性即对应映射元素的键值对数组
}
浏览器的差异会导致两种存储方式占用的内存占用所不同,不过在给定内存大小的情况下,map比Object多存储大约50%的键值对
插入速度上面 map 和 Object性能大致相同, 但是如果代码涉及大量的插入,建议使用map
差异较小,只包含少量键值对的情况下Object更好
Object 的delete()性能较差,而map的删除delete()性能好,如果数据涉及到大量的删除操作,建议使用map
是es6中新增的一种数据类型, 即集合
。
set是一个引用类型的数据
创建set可以使用new
关键字创建
let set = new Set();
// 返回一个空集合
// Set(0) {}
// 创建set时初始化set
// 传入参数(可迭代对象)
// 传入的字符串、数组等会被迭代
let set1 = new Set('123');
console.log(set1);
// Set(3) { '1', '2', '3' }
let set2 = new Set([2,3,4,5]);
console.log(set2);
// Set(4) { 2, 3, 4, 5 }
let set4 = new Set({id: 12, uname: 'Tom'});
console.log(set4);// 报错
//Object参数内部不包含[Symbol.iterable]迭代器接口
// arguments 内部包含有迭代器接口
function sum(){
let set5 = new Set(arguments);
return set5;
}
console.log(sum(1,2,3,5));
// Set(4) { 1, 2, 3, 5 }
add()方法可用于添加集合值,返回添加完成后的集合实例(说明可以链式添加)
let set = new Set();
set.add('1');
set.add(10);
set.add(true);
set.add({});
console.log(set);
// Set(4) { '1', 10, true, {} }
// 链式添加
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
console.log(set2);
// Set(5) { 1, '2', false, { id: 1 }, [ 12 ] }
clear()方法可清除集合所有值
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
console.log(set2);
// Set(5) { 1, '2', false, { id: 1 }, [ 12 ] }
set2.clear();
console.log(set2);
// Set(0) {size: 0}
size属性可查看当前集合包含值的数量
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
console.log(set2);
// Set(5) { 1, '2', false, { id: 1 }, [ 12 ] }
console.log(set2.size);
// 5
delete()方法可删除某个集合元素,返回删除成功或失败的布尔值
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
set2.delete(false); // true
console.log(set2);
// Set(4) {1, '2', {…}, Array(1)}
has()方法可检测某个集合中是否存在某个元素。结果返回布尔值,表示检测到或者找不到
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
console.log(set2.has(1)); // true
console.log(set2.has('2')); // true
console.log(set2.has(true)); // false
注意:以上案例中添加了如==[12]==, =={id: 1}==这样的元素。在这种情况下检测[12],{id: 1}会返回false
let set2 = new Set();
set2.add(1).add('2').add(false).add({id: 1}).add([12]);
console.log(set2.has([12])); // false
console.log(set2.has({id: 1})); // false
这是因为存入的对象或数组是一个地址值,而参数中要查找数组或对象是另一个地址值,所以查找不到指定元素
解决
let set2 = new Set(),
obj = {id: 1},
arr = [12];
set2.add(1).add('2').add(false).add(obj).add(arr);
console.log(set2.has(arr)); // true
console.log(set2.has(obj)); // true
集合:两个范围内的交合部分
这个部分具有唯一性
Set唯一性: set集合内元素是唯一的
set的元素可以是任意类型
set集合是无序的
let s = new Set(['12', 22, true, 22]);
console.log(s, s.size);
// Set(3) {'12', 22, true} 3
Set支持按照顺序迭代, 集合的实例可以提供一个迭代器,能以插入顺序生成集合内容。可以通过values方法即其别名方法keys方法(或者Symbol.iterator属性)取得这个迭代器。
let s = new Set([1, 2, '3', true, 4]);
console.log(s.values === s[Symbol.iterator]); // true
console.log(s.keys === s[Symbol.iterator]); //true
// 拥有迭代器即可迭代
for (let k of s.values()) {
console.log(k, s.values()[k]);
// 1 undefined
// 2 undefined
// 3 undefined
// true undefined
// 4 undefined
}
for (let prop of s.keys()) {
console.log(prop);
// 1
// 2
// 3
// true
// 4
}
for (let p of s[Symbol.iterator]()) {
console.log(p);
// 1
// 2
// 3
// true
// 4
}
// 可以使用forEach相关的api来遍历set集合
s.forEach((value, index) => {
console.log(value, index);
// 1 1
// 2 2
// 3 3
// true true
// 4 4
})
ES6新增的’弱映射’, 是map的兄弟类型,api也是map的子集。JavaScript垃圾回收机制对待这种弱类型map有特殊的处理方式。
和map类型创建方式一致
let wm = new WeakMap();
注意:传入WeakSet集合的元素必须是Object或者继承自Object类型
通过set()方法实现
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakMap
let wm = new WeakMap();
wm.set(obj1, obj1).set(like, like);
console.log(wm);
// WeakMap {{uname: 'Tom', age: 12} => {uname: 'Tom', age: 12}, Array(3) => Array(3)}
使用delete()方法实现删除某一个元素
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakMap
let wm = new WeakMap();
wm.set(obj1, obj1).set(like, like);
wm.delete(obj1);
console.log(wm);
// WeakMap {Array(3) => Array(3)}
使用has()方法实现
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakMap
let wm = new WeakMap();
wm.set(obj1, obj1).set(like, like);
wm.delete(obj1);
console.log(wm.has(obj1), wm.has(like));
// false true
使用get()方法获取对应的元素
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakMap
let wm = new WeakMap();
wm.set(obj1, obj1).set(like, like);
console.log(wm.get(obj1), wm.get(like));
// {uname: 'Tom', age: 12} (3) ['football', 'baskball', 'pingpong']
weakset中的weak意思是弱弱的引用。表示使用WeakSet存储的数据都是弱弱的引用着。不会阻止垃圾回收机制的回收
例
let newWm = new WeakMap();
newWm.set({id: 12});
向弱类型集合中添加一个新的对象,且添加后代码内没有返现该对象的引用,那么这个集合内的该对象将会被垃圾回收机制回收
若是以下这种情况
let m = new WeakMap();
let o = {
uname = 'TOM'
}
m.set(o);
这里向集合内添加一个o对象,且代码内保存着o变量对对象的引用,那么垃圾回收机制便不会立即回收这个对象。若是将o变量重新赋值,那么原来保存的对象变回被回收。
因为WeakMap中的值任何时候都有可能销毁,所以迭代它就显得没有意义,同样也不需要向Map中的Clear()方法
ES6中新增的’弱集合’,WeakSet是Set的兄弟类型,api也是set的子集。JavaScript垃圾回收机制对待这种弱类型set有特殊的处理方式。
和set类型创建方式一致
let ws = new WeakSet();
注意:传入WeakSet集合的元素必须是Object或者继承自Object类型
通过add()方法实现
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakSet
let ws = new WeakSet();
ws.add(obj1).add(like);
console.log(ws);
// WeakSet {{uname: 'Tom', age: 12}, ['football', 'baskball', 'pingpong']}
使用delete()方法实现删除某一个元素
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakSet
let ws = new WeakSet();
ws.add(obj1).add(like);
ws.delete(like);
console.log(ws);
// {uname: 'Tom', age: 12}
使用has()方法实现
let obj1 = {
uname: 'Tom',
age: 12
},
like = ['football', 'baskball', 'pingpong'];
// 创建WeakSet
let ws = new WeakSet();
ws.add(obj1).add(like);
ws.delete(like);
console.log(ws);
// {uname: 'Tom', age: 12}
console.log(ws.has(like), ws.has(obj1));
// false true
weakset中的weak意思是弱弱的引用。表示使用WeakSet存储的数据都是弱弱的引用着。不会阻止垃圾回收机制的回收
例
let newWs = new WeakSet();
newWs.add({id: 12});
向弱类型集合中添加一个新的对象,且添加后代码内没有返现该对象的引用,那么这个集合内的该对象将会被垃圾回收机制回收
若是以下这种情况
let s = new WeakSet();
let o = {
uname = 'TOM'
}
s.add(o);
这里向集合内添加一个o对象,且代码内保存着o变量对对象的引用,那么垃圾回收机制便不会立即回收这个对象。若是将o变量重新赋值,那么原来保存的对象变回被回收。
因为WeakSet中的值任何时候都有可能销毁,所以迭代它就显得没有意义,同样也不需要向Set中的Clear()方法
/*
* WeakSet 避免内存泄漏 -- 被垃圾回收
* */
let obj1 = {
id: 10
}, obj2 = {
bool: true
}
let set = new Set([obj1, obj2]);
console.log(set);
// Set(2) {{id: 10}, {bool: true}}
obj2 = null;
setTimeout(() => {
console.log(set);
// Set(2) {{id: 10}, {bool: true}}
}, 3000)
// -----------------------------------------------------------
let obj3 = {
id: 10
}, obj4 = {
bool: true
}
let wSet = new WeakSet([obj3, obj4]);
console.log(wSet);
// WeakSet {{id: 10}, {bool: true}}
obj4 = null;
setTimeout(() => {
console.log(wSet);
// WeakSet {{id: 10}}
}, 3000);