js中map和普通对象性能差距有多⼤?
背景
当我们需要进⾏⼀些键值对数据的存储时,js 本⾝普通对象可以完成这个过程,es6 中提供了⼀个新的数据结构叫做 Map
⼆者之间性能差距有多⼤呢
js原型和原型链的理解普通对象
const map = {};
// insert key-value-pair
map["key1"] = "value1";
map["key2"] = "value2";
map["key3"] = "value3";
// check if map contians key
if (map.hasOwnProperty("key1")) {
console.log("Map contains key1");
}
// get value with specific key
console.log(map["key1"]);
这种做法很常见,但同时也有很⼤的局限
⽀持键类型
在 js 中,当你使⽤对象 object 时,键 key 只能有 string 和 symbol 。然⽽ Map 的 key ⽀持的就⽐较多了,可以⽀持 string, symbol, number, function, object, 和 primitives
const map = new Map();
const myFunction = () => console.log("I am a useful function.");
const myNumber = 666;
const myObject = {
name: "plainObjectValue",
otherKey: "otherValue",
};
map.set(myFunction, "function as a key");
map.set(myNumber, "number as a key");
map.set(myObject, "object as a key");
console.(myFunction)); // function as a key
console.(myNumber)); // number as a key
console.(myObject)); // object as a key
封装类型带来的便利
size map⼤⼩确定map只需要o(1),普通对象需要o(n)
const map = new Map();
map.set('someKey1', 1);
map.set('someKey2', 1);
...
map.set('someKey100', 1);
console.log(map.size) // 100, Runtime: O(1)
const plainObjMap = {};
plainObjMap['someKey1'] = 1;
plainObjMap['someKey2'] = 1;
...
plainObjMap['someKey100'] = 1;
console.log(Object.keys(plainObjMap).length) // 100, Runtime: O(n)
增删性能
map不需要把所有的键转换为字符串,节省了⼤量的性能
遍历
const map = new Map();
map.set('someKey1', 1);
map.set('someKey2', 2);
map.set('someKey3', 3);
for (let [key, value] of map) {
console.log(`${key} = ${value}`);
}
// someKey1 = 1
// someKey2 = 2
// someKey3 = 3
const plainObjMap = {};
plainObjMap['someKey1'] = 1;
plainObjMap['someKey2'] = 2;
plainObjMap['someKey3'] = 3;
for (let key of Object.keys(plainObjMap)) {
const value = plainObjMap[key];
console.log(`${key} = ${value}`);
}
// someKey1 = 1
// someKey2 = 2
// someKey3 = 3
顺序问题
对象中的key 是不保证顺序的,因为对于 number 是存放到 elements 中,会按照从⼩到⼤,对于字符串类型的是存放到 properties 中,会按照添加的顺。
map 是保证顺序的,按照添加的顺序依次出来的。
原型链问题
普通对象继承了很多原型⽅法,如toString
⽽map是⼲净的!
从 ECMAScript 2015 开始,如果你坚持使⽤原⽣的对象,你可以 ate(null) 来⽣成⼀个⼲净的 object *