关于javascript:深究-Map-和-Object-的区别

67次阅读

共计 1918 个字符,预计需要花费 5 分钟才能阅读完成。

家喻户晓 JavaScriptObjectMap 这两种数据结构很类似,
但深究底层原理来看,这两者实质上还是存在了不少差别,通过区别比拟能帮忙咱们更好地了解它们的用途和应用场景。

键类型

Object

Object 的键必须是 StringSymbol 类型,并默认调用 toString 办法将键转化为 String 类型,因而可能会存在同名键笼罩问题。

注:ArrayFunction 实质是对 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,即 MapObject 的实例对象,反之 Object 并不是 Map 的实例对象。

参考文档

ECMA 官网文档

正文完
 0