本文内容
在Map出现之前,要实现类似需求,只能使用Object,但是Object还是存在一些问题的。
Map 对象保存键值对。任何值(对象或者原始值) 都可以作为一个键或一个值。
new Map([iterator])
const map = new Map();
// Create
map.set('name','xialei');
map.set('site', 'https://www.ddhigh.com');
// Update
map.set('name', 'xialeistudio');
// Read
map.get('name');
// Delete
map.delete('name');
// 清空
map.clear();
// map大小
console.log(map.size);
JS中基本数据类型有string、number、boolean、null、undefined、symbol,复杂数据类型有object(包括object,array,function等),还有个特殊的NaN(typeof结果是number),分别对这些类型进行测试
const map = new Map();
const sKey = 'key',
nKey = 1,
bKey = true,
nullKey = null,
uKey = undefined,
symbolKey = Symbol("key"),
oKey = {},
ooKey = oKey,
aKey = [],
fKey = function () { },
nanKey = NaN;
map.set(sKey, "string")
.set(nKey, "number")
.set(bKey, "boolean")
.set(nullKey, "null")
.set(uKey, "undefined")
.set(symbolKey, "symbol")
.set(oKey, "object")
.set(aKey, "array")
.set(fKey, "function")
.set(nanKey, "NaN");
console.log(map);
console.log(map.get(sKey) === "string", map.get("key") === "string");
console.log(map.get(nKey) === "number", map.get(1) === "number");
console.log(map.get(bKey) === "boolean", map.get(true) === "boolean");
console.log(map.get(nullKey) === "null", map.get(null) === "null");
console.log(map.get(uKey) === "undefined", map.get(undefined) === "undefined");
console.log(map.get(symbolKey) === "symbol");
console.log(map.get(oKey) === "object", map.get({}) === "object", map.get(oKey) === map.get(ooKey));
console.log(map.get(aKey) === "array", map.get([]) === "array");
console.log(map.get(fKey) === "function", map.get(function () { }) === "function");
console.log(map.get(nanKey) === "NaN", map.get(NaN) === "NaN");
输出如下
Map {
'key' => 'string',
1 => 'number',
true => 'boolean',
null => 'null',
undefined => 'undefined',
Symbol(key) => 'symbol',
{} => 'object',
[] => 'array',
[Function: fKey] => 'function',
NaN => 'NaN'
}
true true
true true
true true
true true
true true
true
true false true
true false
true false
true true
结论
同时迭代键值
// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const [k, v] of map) {
console.log(k, v);
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const [k, v] of map.entries()) {
console.log(k, v);
}
迭代键
// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const k of map.keys()) {
console.log(k, map.get(k));
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const [k] of map.entries()) { // 解构赋值
console.log(k, map.get(k));
}
迭代值
// 普通版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const v of map.values()) {
console.log(v);
}
// 迭代器版本
const map = new Map();
map.set("1", 1);
map.set("2", 2);
for (const [,v] of map.entries()) {
console.log(v);
}
forEach()
forEach方法的顺序是value, key,不是key, value!
const map = new Map();
map.set("1", 1);
map.set("2", 2);
map.forEach((value, key) => {
console.log(value, key);
});
const obj = {
name: 'xialei',
site: 'https://www.ddhigh.com'
};
const map = new Map(obj);
console.log(map);
执行报错TypeError: object is not iterable,因为Object不是可迭代对象。
可迭代对象:ES6新出的语法,对象或对象的原型链实现了Symbol.iterator方法,关于迭代器的内容将在下一篇文章中详细介绍
我们给Object.prototype添加属性方法来支持迭代:
warning: 正式代码请谨慎修改原型链!
const obj = {
name: 'xialei',
site: 'https://www.ddhigh.com'
};
Object.prototype[Symbol.iterator] = function () { // Symbol.iterator可以理解为全局唯一的标识
const keys = Object.keys(this);
let keyIndex = 0;
return {
next() {
if (keyIndex < keys.length) {
const key = keys[keyIndex++];
return { value: [key, obj[key]] }; // 迭代值
}
return { done: true }; // 迭代结束
}
}
};
const map = new Map(obj);
console.log(map);
只支持[[key, value]]这种二维数组。二维数组的每一个元素包含key和value两个子元素
const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);
由于Map是可迭代对象,因此可以作为参数传给Map构造函数
两个Map的元素是一样的,不是Map不相等,因为不是同一个对象
const map = new Map([['name', 'xialeistudio'], ['site', 'https://www.ddhigh.com']]);
const map2 = new Map(map);
console.log(map === map2); // false
多个Map可以合并,相同key会被覆盖,规则为后面的覆盖前面的
const map = new Map([
[1, 1],
[2, 2]
]);
const map2 = new Map([
[1, 2]
]);
const map3 = new Map([...map, ...map2]);
console.log(map3); // Map { 1 => 2, 2 => 2 }
Map的出现解决了传统object无法直接解决的问题,更好地向标准编程语言靠近(标准编程语言一般会提供Map集合),使用的坑也比较少(比如没有object作为key时转换为[object Object]的问题)。
Javascript 一直是神奇的语言。 不相信我? 尝试使用map和parseInt将字符串数组转换为整数。打开 Chrome 的控制台(F12),粘贴以下内容,然后按回车,查看输出结果:
在 Javascript 中,一个函数可以传递任何多个数量的参数,即使调用时传递的数量与定义时的数量不一致。缺失的参数会以 undefined 作为实际值传递给函数体,然后多余的参数会直接被忽略掉
在JavaScript中,Map 是存储键/值对的对象。Map 类似于一般 JavaScript 对象 ,但对象与 Map 之间一些关键的差异使 Map 很有用。如果你要创建一个存储一些键/值路径的 JavaScript 对象
Map、Set的polyfill实现是可以继承的;//可继承的Array替换原生Array,Array要改的地比较多,除了替换原生Array还需修改继承函数,供参考
普通的 JavaScript 对象通常可以很好地保存结构化数据。但是它们有一些限制:只能用字符串或符号用作键,自己的对象属性可能会与从原型继承的属性键冲突(例如,toString,constructor 等)。对象不能用作键
ES6 提供了新的数据结构 Set。它类似于数组,但是成员的值都是唯一的,没有重复的值。JavaScript 的对象(Object),本质上是键值对的集合(Hash 结构),但是传统上只能用字符串当作键。这给它的使用带来了很大的限制。
ES6的Map的键可以是任意的数据结构,并且不重复。那么map的底层原理是啥呢?Map利用链表,hash的思想来实现。首先,Map可以实现删除,而且删除的数据可以是中间的值。
JavaScript中,数组的遍历我们肯定都不陌生,最常见的两个便是forEach 和 map。(当然还有别的譬如for, for in, for of, reduce, filter, every, some, ...)
JS 普通对象 {key: value} 用于存放结构化数据。但有一件事我觉得很烦:对象键必须是字符串(或很少使用的 symbol)。如果将数字用作键会怎样? 在这种情况下不会有错误:
JSON 对象保存在大括号内。就像在JavaScript中, 对象可以保存多个 键/值 对。Map对象保存键/值对,是键/值对的集合。任何值(对象或者原始值) 都可以作为一个键或一个值。Object结构提供了“字符串—值”的对应
内容以共享、参考、研究为目的,不存在任何商业目的。其版权属原作者所有,如有侵权或违规,请与小编联系!情况属实本人将予以删除!