Map 和 Set-有序和无序
有序和无序,先看个例子
html
<p class="container" style="color: red" id="p1">
<img src="xxx" alt="xxx.png" />
<span>123</span>
</p>
<script>
// vdom 虚拟 dom - 模拟真是的 dom 结构
const p = {
tag: 'p',
props: {
// 无序
id: 'p1',
className: 'container',
style: 'color:red',
},
children: [
// 有序
{
tag: 'img',
props: {
alt: 'xxx',
src: 'xxx.png',
},
},
{
tag: 'span',
children: [123],
},
],
};
// js 中 Object 是无序的,Array 是有效的
</script>
- 有序:操作慢
- 无序:操作快,但无序
- 如何结合两者优点呢? - 二叉树、及其变种
Map 和 Object 的区别
- API 不同,Map 可以以任意类型为 key
- Map 是有序结构(重要)
- Map 操作同样很快
js
const obj1 = {
2: 'hello',
1: { x: 100 },
3: 100,
};
// Object 是无序的
console.log(Object.keys(obj1)); // ['1', '2', '3']
// Object 有多快?
for (let i = 0; i < 1000 * 10000; i++) {
obj1[i + ''] = i;
}
console.time('obj find');
obj1['2000000'];
console.timeEnd('obj find'); // obj find: 0.0068359375 ms
// Map Api: set,delete,has,forEach,size
const m = new Map([
['key1', 'hello'],
['key3', { x: 100 }],
['key2', 100],
]);
// Map 的 key 可以为任意类型
const obj2 = { name: 'xxx' };
m.set(obj2, 'object key');
function fn() {}
m.set(fn, 'fn key');
// 比如 obj1 和 obj2 关联,但是没有引用关系,保持独立
// m.set(obj1, obj2)
// Map 是有序的
m.forEach((value, key) => console.log(key, value)); // 保持顺序输出
// Map 有多快?
for (let i = 0; i < 1000 * 10000; i++) {
m.set(i + '', i);
}
console.time('map find');
m.has('2000000');
console.timeEnd('map find'); // map find: 0.01416015625 ms
Set 和 Array 的区别
- API 不同
- Set 元素不能重复
- Set 是无序结构,操作很快
js
const arr = [1, 2, 3, 4];
const set = new Set([1, 2, 2, 3, 4]);
// Map Api: add,delete,has,forEach,
set.forEach((val) => console.log(val));
// Set 元素是不能重复的(数组去重)
console.log(set); // Set(4){1, 2, 3, 4}
// Set 是无序的(快),arr 是有序的(慢)
for (let i = 0; i < 100 * 10000; i++) {
arr.push(i);
}
console.time('arr unshift');
arr.unshift('a'); // 导致所有元素后移,所以慢
console.timeEnd('arr unshift'); // arr unshift: 0.25390625 ms
console.time('arr push');
arr.push('b');
console.timeEnd('arr push'); // arr push: 0.005859375 ms
console.time('arr find');
arr.includes('20000');
console.timeEnd('arr find'); // arr find: 0.89794921875 ms
for (let i = 0; i < 100 * 10000; i++) {
set.add(i);
}
console.time('set add');
set.add('a');
console.timeEnd('set add'); // set add: 0.00390625 ms
console.time('set find');
set.has('20000');
console.timeEnd('set find'); // set find: 0.005859375 ms