家喻户晓 JavaScript
的 Object
和 Map
这两种数据结构很类似,
但深究底层原理来看,这两者实质上还是存在了不少差别,通过区别比拟能帮忙咱们更好地了解它们的用途和应用场景。
键类型
Object
Object
的键必须是 String
或 Symbol
类型,并默认调用 toString
办法将键转化为 String
类型,因而可能会存在同名键笼罩问题。
注:Array
和Function
实质是对Object
的继承,因而都有对应的toString
办法。
对象键
将对象作为键时会调用 Object.toString
办法将其转化为对象字符串 ("[object Object]"
)。
({}.toString()); // "[object Object]"var obj = {};obj[{}] = "ok";console.log(JSON.stringifpwdy(obj)); // {"[object Object]":"ok"}
数组键
将数组作为键时会调用 Array.toString
办法将其转化为空字符串 (""
)。
[].toString(); // ""var obj = {};obj[[]] = "ok";console.log(JSON.stringify(obj)); // {"":"ok"}
函数键
将函数作为键时会调用 Function.toString
办法将其转化为函数字符串 ("() => {}"
)。
(function test() => {}).toString(); // "() => {}"var obj = {};obj[() => {}] = "ok";console.log(JSON.stringify(obj)); // {"() => {}":"ok"}
Map
Map
反对任意类型的键。
Map objects are collections of key/value pairs where both the keys and values may be arbitrary ECMAScript language values.
键唯一性
Object 同名键笼罩
因为 Object
的键默认会调用 toString
办法,因而以后键如果是空对象({}
)或者空数组([]
)的话,屡次赋值会呈现被笼罩的状况。
var obj = {};obj[{}] = "step1";obj[{}] = "step2";console.log(JSON.stringify(obj)); // {"[object Object]":"step2"}
Map 惟一键
在 Map
中每个键都是惟一的,在存储过程中 Map
会对存入键的 类型
或 援用
进行比拟。假如以后 Map
存入了两个空对象({}
),两者类型雷同,但在 栈
中援用的内存地址不同,那么 Map
就会认定为是两个独立键,示例如下:
遍历秩序
Object 无序
在遍历 Object
后失去的后果是一个无序列表。
var obj = { 1: 1, 2: 2, a: "a", f: "f" };console.log(Object.keys(obj)); // ["1", "2", "a", "f"]obj = { a: "a", 1: 1, 2: 2, f: "f" };console.log(Object.keys(obj)); // ["1", "2", "a", "f"]
Map 有序
在遍历 Map
后失去的后果是一个有序列表。
var map = new Map();map.set(1, 1);map.set("a", "a");map.set(2, 2);console.log([...map.values()]); // [1, "a", 2]
可遍历
Object
Object
没有实现遍历器(@@iterator
)接口,无奈应用 for of
遍历,但能够用 for in
等办法遍历。当然,Object
原生不反对但能够扩大 @@iterator
实现遍历,详见 iterator。
var obj = { a: "a", 1: 1, 2: 2, f: "f" };for (key in obj) { if (obj.hasOwnProperty(key)) { console.log(key); }}console.log(Object.keys(obj)); // ["1", "2", "a", "f"]
Map
Map
外部实现了遍历器(@@iterator
)接口,能够应用 for of
遍历。
Map.prototype [ @@iterator ] ( )
var map = new Map();map.set(1, 1);map.set("a", "a");map.set(2, 2);for (item of map) { console.log(item);}
继承关系
从原型链继承构造中,咱们能够看到 Map
底层实际上是继承自 Object
,即 Map
是 Object
的实例对象,反之 Object
并不是 Map
的实例对象。
参考文档
ECMA 官网文档