Set
console.log(new Set());
add
add向其中添加元素 放回的是set结构本身
var set = new Set();
set.add(5);
set.add(7);
console.log(set);
var set = new Set([5, 7]);
console.log(set);
参数必须是具备iterator接口的数据结构 数组 类数组
我们发现这里NaN是等于NaN的
var set = new Set([undefined, undefined, null, null, 5, '5', NaN, NaN, true, 1, {}, {}]);
console.log(set);
add可以链式调用
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
console.log(set);
size
size 相当于长度
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
console.log(set.size);
delete
delete删除元素 返回值是一个布尔值 true 删除
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
console.log(set.delete(y));
console.log(set);
clear
clear清空set中的所有值 返回值是undefined
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
set.clear();
console.log(set);
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
console.log(set.clear());
has
has 是否含有某个元素
var set = new Set();
var x = { id: 1 },
y = { id: 2 };
set.add(x).add(y);
console.log(set.has(x));
在使用delete删除某个元素的时候 下面的情况需要注意
如果在删除之前就打印 打印的结果是删除之后的结果
我们先看一下普通的情况
var obj = { a: 1, b: 2 };
console.log(obj);
delete obj.a;
console.log(obj);
看一下set的情况
虽然显示有 但是内部其实是没有的
var set = new Set();
set.add(1).add(2);
console.log(set);
set.delete(1);
keys values entires
返回的都是迭代器对象
let set = new Set([1, 2, 3, 4, 5, 6]);
console.log(set.keys());
console.log(set.values());
console.log(set.entries());
keys 返回一个键名的迭代器
values 返回一个键值的迭代器
entires 返回一个键值对的迭代器
let set = new Set(['a', 'b', 'c', 'd', 'e', 'f']);
for (let i of set.keys()) {
console.log(i);
}
for (let i of set.values()) {
console.log(i);
}
for (let i of set.entries()) {
console.log(i);
}
当我们使用for of 直接迭代set时 其实是调用set.values()
let set = new Set(['a', 'b', 'c', 'd', 'e', 'f']);
for (let values of set) {
console.log(values);
}
console.log(Set.prototype[Symbol.iterator] === Set.prototype.values);
实现交集 并集 差集
let a = new Set([1, 2, 3]);
let b = new Set([4, 3, 2]);
let union = new Set([...a, ...b]);
console.log(union);
let intersect = new Set([...a].filter((x) => b.has(x)));
console.log(intersect);
let difference = new Set([...a].filter((x) => !b.has(x)));
console.log(difference);
map
console.log(new Map());
我们来看一种情况
let arr = [1, 2, 3, 4];
let arr1 = arr.map(parseInt);
console.log(arr1);
为什么会出现这种情况呢
因为 map 中的第一个参数是遍历到的元素 第二个参数是当前元素的索引
而parseInt可以传入两个参数 第一个参数是要转换的 第二个参数是当前元素的进制
所以 就变成了这种情况
console.log(parseInt(1, 0));
console.log(parseInt(2, 1));
console.log(parseInt(3, 2));
console.log(parseInt(4, 3));
let set = [1, 2, 3, 4, 5];
let set2 = new Set([[...set.map(parseInt)]]);
console.log(set2);
对于普通情况 键名与键值不是一一对应的
当键名是一个对象会调用toSting方法 所以会覆盖
var m = {};
var x = { id: 1 },
y = { id: 2 };
m[x] = 'foo';
m[y] = 'bar';
console.log(m);
console.log(m[x]);
console.log(m[y]);
let m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo');
m.set(y, 'bar');
console.log(m.get(x));
console.log(m.get(y));
set
参数 具备iterator接口的数据结构
必须要是双元数组结构
传参的方式一
let m = new Map([
['name', 'zhangsan'],
['title', 'lisi'],
]);
console.log(m);
传参的方式二
let m = new Map();
m.set('name', 'zhangsan');
m.set('title', 'lisi');
console.log(m);
当我们再次声明时 会覆盖
let m = new Map([
['name', 'zhangsan'],
['title', 'lisi'],
]);
m.set('name', 'wangwu');
console.log(m);
传参的方式三
let items = [
['name', 'wangwu'],
['title', 'zhangsan'],
];
let m = new Map();
items.forEach(([key, value]) => m.set(key, value));
console.log(m);
get
当键名是引用值时 是拿不到的
const map = new Map();
map.set({}, 555);
console.log(map.get({}));
const map = new Map();
map.set([5], 555);
console.log(map.get([5]));
要使用一个指针保存
const map = new Map();
var m = [5];
map.set(m, 555);
console.log(map.get(m));
对于原始值
const map = new Map();
map.set(1, 'foo');
console.log(map.get(1));
const map = new Map();
map.set(-0, 555);
console.log(map.get(+0));
const map = new Map();
map.set(true, -1);
map.set('true', 1);
console.log(map.get(true));
const map = new Map();
map.set(undefined, -1);
map.set(null, 1);
console.log(map.get(undefined));
console.log(map.get(null));
const map = new Map();
map.set(NaN, 123);
console.log(map.get(NaN));
set返回当前Map 所以可以链式调用
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m);
size
返回键值对的个数
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m);
console.log(m.size);
delete
删除键值对
与set一样先删除 后打印
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m);
console.log(m.delete(x));
has
是否有某个键值对
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m.has(x));
clear
全部删除 返回undefined
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m.clear());
console.log(m);
keys values entires
返回的都是迭代器对象
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
console.log(m.keys());
console.log(m.values());
console.log(m.entries());
当我们使用for of 直接迭代map时 其实是调用map.entries
const m = new Map();
var x = { id: 1 },
y = { id: 2 };
m.set(x, 'foo').set(y, 'bar');
for (let keys of m.keys()) {
console.log(keys);
}
for (let values of m.values()) {
console.log(values);
}
for (let entries of m.entries()) {
console.log(entries);
}
for (let entries of m) {
console.log(entries);
}
for (let [key, value] of m) {
console.log(key, value);
}
console.log(m[Symbol.iterator] === m.entries);
map转换为对象
const myMap = new Map();
myMap.set(true, 7).set(1, 'abc');
function strMapToObj(strMap) {
let obj = Object.create(null);
for (let [key, value] of strMap) {
console.log(key, value);
obj[key] = value;
}
return obj;
}
console.log(strMapToObj(myMap));
对象转换为map
function objToString(obj) {
let map = new Map();
for (let key of Object.keys(obj)) {
map.set(key, obj[key]);
}
return map;
}
console.log(objToString({ true: 7, no: false }));
数组转换为map
const map = new Map([
[true, 7],
[{ foo: 3 }, ['abc']],
]);
console.log(map);
map转换为数组
const myMap = new Map();
myMap.set(true, 7).set({ foo: 3 }, ['abc']);
console.log([...myMap]);
WeakMap WeakMap
成员只能是对象
console.log(new WeakMap());
console.log(new WeakSet());