中文字幕av专区_日韩电影在线播放_精品国产精品久久一区免费式_av在线免费观看网站

溫馨提示×

溫馨提示×

您好,登錄后才能下訂單哦!

密碼登錄×
登錄注冊×
其他方式登錄
點擊 登錄注冊 即表示同意《億速云用戶服務條款》

怎么使用JavaScript的Map提升性能

發布時間:2022-05-06 16:32:43 來源:億速云 閱讀:360 作者:iii 欄目:大數據

這篇文章主要介紹“怎么使用JavaScript的Map提升性能”,在日常操作中,相信很多人在怎么使用JavaScript的Map提升性能問題上存在疑惑,小編查閱了各式資料,整理出簡單好用的操作方法,希望對大家解答”怎么使用JavaScript的Map提升性能”的疑惑有所幫助!接下來,請跟著小編一起來學習吧!

Map與常規對象有什么不同

Map和常規對象主要有2個不同之處。

1.無限制的鍵(Key)

常規JavaScript對象的鍵必須是String或Symbol,下面的對象說明的這一點:

const symbol = Symbol();
const string2 = 'string2';

const regularObject = {
 string1: 'value1',
 [string2]: 'value2',
 [symbol]: 'value3'
};

相比之下,Map允許你使用函數、對象和其它簡單的類型(包括NaN)作為鍵,如下代碼:

const func = () => null;
const object = {};
const array = [];
const bool = false;
const map = new Map();

map.set(func, 'value1');
map.set(object, 'value2');
map.set(array, 'value3');
map.set(bool, 'value4');
map.set(NaN, 'value5');

在鏈接不同數據類型時,這個特性提供了極大的靈活性。

2.直接遍歷

在常規對象中,為了遍歷keys、values和entries,你必須將它們轉換為數組,如使用Object.keys()、Object.values()和Object.entries(),或者使用for ... in循環,因為常規對象不能直接遍歷,另外for ... in循環還有一些限制:它僅僅遍歷可枚舉屬性、非Symbol屬性,并且遍歷的順序是任意的。
而Map可以直接遍歷,并且由于它是鍵控集合,遍歷的順序和插入鍵值的順序是一致的。你可以使用for ... of循環或forEach方法來遍歷Map的entries,如下代碼:

for (let [key, value] of map) {
 console.log(key);
 console.log(value);
};
map.forEach((key, value) => {
 console.log(key);
 console.log(value);
});

還有一個好處就是,你可以調用map.size屬性來獲取鍵值數量,而對于常規對象,為了做到這樣你必須先轉換為數組,然后獲取數組長度,如:Object.keys({}).length。

Map和Set有何不同

Map的行為和Set非常相似,并且它們都包含一些相同的方法,包括:has、get、set、delete。它們兩者都是鍵控集合,就是說你可以使用像forEach的方法來遍歷元素,順序是按照插入鍵值排列的。
最大的不同是Map通過鍵值(key/value)成對出現,就像你可以把一個數組轉換為Set,你也可以把二維數組轉換為Map:

const set = new Set([1, 2, 3, 4]);
const map = new Map([['one', 1], ['two', 2], ['three', 3], ['four', 4]]);

類型轉換

要將Map切換回數組,你可以使用ES6的結構語法:

const map = new Map([['one', 1], ['two', 2]]);
const arr = [...map];

到目前為止,將Map與常規對象的互相轉換依然不是很方便,所以你可能需要依賴一個函數方法,如下:

const mapToObj = map => {
 const obj = {};
 map.forEach((key, value) => { obj[key] = value });
 return obj;
};
const objToMap = obj => {
 const map = new Map();
 Object.keys(obj).forEach(key => { map.set(key, obj[key]) });
 return map;
};

但是現在,在八月份ES2019的首次展示中,我們看見了Object引入了2個新方法:Object.entries()和Object.fromEntries(),這可以使上述方法簡化許多:

const obj2 = Object.fromEntries(map);
const map2 = new Map(Object.entries(obj));

在你使用Object.fromEntries轉換map為object之前,確保map的key在轉換為字符串時會產生唯一的結果,否則你將面臨數據丟失的風險。

性能測試

為了準備測試,我會創建一個對象和一個map,它們都有1000000個相同的鍵值。

let obj = {}, map = new Map(), n = 1000000;
for (let i = 0; i < n; i++) {
 obj[i] = i;
 map.set(i, i);
}

然后我使用console.time()來衡量測試,由于我特定的系統和Node.js版本的原因,時間精度可能會有波動。測試結果展示了使用Map的性能收益,尤其是添加和刪除鍵值的時。

查詢

let result;
console.time('Object');
result = obj.hasOwnProperty('999999');
console.timeEnd('Object');
// Object: 0.250ms

console.time('Map');
result = map.has(999999);
console.timeEnd('Map');
// Map: 0.095ms (2.6 times faster)

添加

console.time('Object');
obj[n] = n;
console.timeEnd('Object');
// Object: 0.229ms

console.time('Map');
map.set(n, n);
console.timeEnd('Map');
// Map: 0.005ms (45.8 times faster!)

刪除

console.time('Object');
delete obj[n];
console.timeEnd('Object');
// Object: 0.376ms

console.time('Map');
map.delete(n);
console.timeEnd('Map');
// Map: 0.012ms (31 times faster!)

Map在什么情況下更慢

在測試中,我發現一種情況常規對象的性能更好:使用for循環去創建常規對象和map。這個結果著實令人震驚,但是沒有for循環,map添加屬性的性能勝過常規對象。

console.time('Object');
for (let i = 0; i < n; i++) {
 obj[i] = i;
}
console.timeEnd('Object');
// Object: 32.143ms

let obj = {}, map = new Map(), n = 1000000;
console.time('Map');
for (let i = 0; i < n; i++) {
 map.set(i, i);
}
console.timeEnd('Map');
// Map: 163.828ms (5 times slower)

舉個例子

最后,讓我們看一個Map比常規對象更合適的例子,比如說我們想寫一個函數去檢查2個字符串是否由相同的字符串隨機排序。

console.log(isAnagram('anagram', 'gramana')); // Should return true
console.log(isAnagram('anagram', 'margnna')); // Should return false

有許多方法可以做到,但是這里,map可以幫忙我們創建一個最簡單、最快速的解決方案:

const isAnagram = (str1, str2) => {
 if (str1.length !== str2.length) {
  return false;
 }
 const map = new Map();
 for (let char of str1) {
  const count = map.has(char) ? map.get(char) + 1 : 1;
  map.set(char, count);
 }
 for (let char of str2) {
  if (!map.has(char)) {
   return false;
  }
  const count = map.get(char) - 1;
  if (count === 0) {
   map.delete(char);
   continue;
  }
  map.set(char, count);
 }
 return map.size === 0;
};

在這個例子中,當涉及到動態添加和刪除鍵值,無法提前確認數據結構(或者說鍵值的數量)時,map比object更合適。

到此,關于“怎么使用JavaScript的Map提升性能”的學習就結束了,希望能夠解決大家的疑惑。理論與實踐的搭配能更好的幫助大家學習,快去試試吧!若想繼續學習更多相關知識,請繼續關注億速云網站,小編會繼續努力為大家帶來更多實用的文章!

向AI問一下細節

免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。

AI

长沙市| 米林县| 奉化市| 元阳县| 屯昌县| 师宗县| 顺昌县| 南涧| 江北区| 桦甸市| 旬邑县| 望城县| 托克逊县| 长垣县| 福泉市| 河西区| 措勤县| 黄陵县| 文化| 汽车| 岐山县| 山东| 东城区| 晋州市| 太原市| 五寨县| 黔西| 任丘市| 湟源县| 策勒县| 华坪县| 石阡县| 祁东县| 汽车| 郧西县| 磐石市| 西安市| 海盐县| 海宁市| 衡山县| 垫江县|