狠狠色丁香婷婷综合尤物/久久精品综合一区二区三区/中国有色金属学报/国产日韩欧美在线观看 - 国产一区二区三区四区五区tv

LOGO OA教程 ERP教程 模切知識交流 PMS教程 CRM教程 開發(fā)文檔 其他文檔  
 
網(wǎng)站管理員

只會用Object?我想推薦你試試Map

freeflydom
2023年10月25日 15:18 本文熱度 506

導(dǎo)讀

Javascript中,我們經(jīng)常使用Object對象來實現(xiàn)鍵值對存儲的功能,但是Object有一些缺點和局限性。為了解決這些問題,ES6引入了一個新的數(shù)據(jù)結(jié)構(gòu):MapMap是一個有序的鍵值對集合,它可以存儲任意類型的鍵和值,并且提供了許多便捷的方法。

本文將介紹MapObject的基本用法和區(qū)別,并且說明為什么更推薦大家使用Map。


對于Object來說,增刪鍵值對的性能比較差。而在MDN中,特別提到Map對象對增刪鍵值對的操作進行了優(yōu)化,如圖所示:

為什么

這與Javascript虛擬機優(yōu)化對象的方式有關(guān),虛擬機通過假定對象的結(jié)構(gòu)來優(yōu)化代碼執(zhí)行效率。而Map是專門用于哈希映射的,其中鍵值是動態(tài)且不斷變化的。那么至于為什么沒有對Object對象增刪鍵進行優(yōu)化的原因感興趣的小伙伴可以閱讀這篇文章。

可迭代性

首先,首先,Object沒有實現(xiàn)迭代協(xié)議,所以for…of語句并不能直接迭代對象。這一點在MDN中也有說明:

對象

對象的遍歷

由于對象不能使用使用for...of,所以我們只能使用for...in來遍歷,但是使用for...in的話,會有如下問題:

  • 會遍歷對象所有的可枚舉屬性,包括原型鏈上的屬性

  • 遍歷順序不一定按照對象屬性定義的順序

  • 遍歷的索引為字符串類型的數(shù)字,并不能直接進行計算

下面就舉例說明一下這些問題

1. 會遍歷對象所有的可枚舉屬性,包括原型鏈上的屬性,例如

function Person(name) {

  this.name = name;

}


Person.prototype.sayHello = function() {

  console.log("Hello, I'm " + this.name);

};


var obj = new Person("Tom");


for (const prop in obj) {

    console.log(prop) // name, sayHello

}


可以看到obj除了自身屬性name之外,還會遍歷到原型鏈上的屬性sayHello。這是因為sayHello可枚舉的。
所以,通常我們需要這樣這樣寫:

// 方法一:使用hasOwnProperty()

for (var prop in obj) {

  if (obj.hasOwnProperty(prop)) {

    console.log(prop); // name

  }

}


// 方法二:使用Object.keys()

var keys = Object.keys(obj);

for (var i = 0; i < keys.length; i++) {

  console.log(keys[i]); // name

}


2. 遍歷順序不一定按照對象屬性定義的順序,例如:

const obj = {

  a: 1,

  b: 2,

  c: 3,

  "1": "one",

  "2": "two",

  "3": "three"

};


for (var key in obj) {

  console.log(key + ": " + obj[key]);

}


這個在谷歌瀏覽器中會先遍歷數(shù)字類型的屬性,如圖:

3. 遍歷的索引為字符串類型的數(shù)字,并不能直接進行計算,例如

const obj = {

  1: "one",

  2: "two",

  3: "three"

};


for (const key in obj) {

  console.log(key, typeof key); // 1 string; 2 string; 3 string

}


const arr = [4, 5, 6]

for (const index in arr) {

 console.log(index, typeof index); // 0 string; 1 string; 2 string;

}


Map

如果是Map,你可以使用標準的for循環(huán)、標準的迭代器和使用解構(gòu)來獲取keyvalue,例如:

const map1 = new Map();


map1.set('a', 1);

map1.set('b', 2);

map1.set('c', 3);


for (const [key, value] of map1) {

 console.log(key, value) // a 1; b 2; c 3

}


對于對象,我們還有一個Object.entries() 來做類似的事情,盡管它看起來不是那么流行,但確實可以

const myObject = {a: 1, b: 2, c: 3}


for (const [key, value] of Object.entries(myObject)) {

 console.log(key, value) // // a 1; b 2; c 3

}


對于Map,你有更簡單的辦法直接內(nèi)置迭代:

// 你可以只便利values,keys


for (const value of myMap.values()) {

 console.log(value)

}


for (const key of myMap.keys()) {

 console.log(key)

}


key

內(nèi)置key

當我們這樣創(chuàng)建一個對象時:

const myMap = {}


myMap.valueOf // => [Function: valueOf]

myMap.toString // => [Function: toString]

myMap.hasOwnProperty // => [Function: hasOwnProperty]

myMap.isPrototypeOf // => [Function: isPrototypeOf]

myMap.propertyIsEnumerable // => [Function: propertyIsEnumerable]

myMap.toLocaleString // => [Function: toLocaleString]

myMap.constructor // => [Function: Object]


盡管對象看起來是個空的,你也可以訪問這些屬性,在MDN中也提到了這個問題:

key的順序

Map保留了鍵的順序,我們可以根據(jù)它明確的順序,直接結(jié)構(gòu)出鍵值:

const [[firstKey, firstValue]] = myMap


實現(xiàn)LRU緩存

用此特性,我們可以實現(xiàn)一個O(1)LRU緩存

什么是LRU緩存?
LRU緩存是一種緩存淘汰策略,它的全稱是Least Recently Used,意思是最近最少使用。它的原理是認為最近使用過的數(shù)據(jù)應(yīng)該是有用的,而很久沒用過的數(shù)據(jù)應(yīng)該是無用的,所以當緩存滿了時,就優(yōu)先刪除那些很久沒用過的數(shù)據(jù),給新數(shù)據(jù)騰出空間。
那么我們用Map實現(xiàn)一下LRU緩存。

class LRUCache {

  constructor(capacity) {

    this.capacity = capacity; // 緩存容量

    this.map = new Map(); // 使用Map存儲鍵值對

  }


  // 獲取鍵對應(yīng)的值,如果不存在則返回 -1

  get(key) {

    if (this.map.has(key)) {

      let value = this.map.get(key);

      this.map.delete(key); // 刪除該鍵值對

      this.map.set(key, value); // 將該鍵值對重新插入到Map末尾,表示最近使用過

      return value;

    } else {

      return -1;

    }

  }


  // 設(shè)置或更新鍵和值,如果超過緩存容量,則刪除最久未使用的鍵值對

  put(key, value) {

    if (this.map.has(key)) {

      this.map.delete(key);

    } else if (this.map.size >= this.capacity) { // 如果Map中沒有該鍵,且已達到緩存容量上限

      let oldestKey = this.map.keys().next().value; // 獲取Map中第一個(最久未使用)的鍵

      this.map.delete(oldestKey);

    }

    this.map.set(key, value); // 將新的或更新的鍵值對插入到Map末尾,表示最近使用過 

  }

}


key的類型

Map甚至可以做一些對象實現(xiàn)不了的事情:

myMap.set({}, value)

myMap.set([], value)

myMap.set(document.body, value)

myMap.set(function() {}, value)

myMap.set(myDog, value)


Object中,key必須是字符串、數(shù)字或者Symbol類型,而在Map中則可以是任何類型,包括函數(shù)、對象或者任何原始值。這意味著,在Map中,我們可以用一個Object來作為一個元素的key

復(fù)制與轉(zhuǎn)換

復(fù)制

你可能會覺得對象更容易復(fù)制,比如:

const copied = {...myObject}

const copied = Object.assign({}, myObject)


但,實際上Map也容易復(fù)制:

js復(fù)制代碼const copied = new Map(myMap)


同樣,你還可以使用structuredClone 深拷貝:

const copied = new Map(myMap)


轉(zhuǎn)換

// Map轉(zhuǎn)對象

const myObj = Object.fromEntries(myMap)


// 對象轉(zhuǎn)Map

const myMap = new Map(Object.entries(myObj))


因此,我們可以不使用元組構(gòu)造映射,可以將它們構(gòu)造成對象,這樣看起來更加美觀:

const myMap = new Map([['key', 'value'], ['keyTwo', 'valueTwo']])


// 可以寫成

const myMao = new Map(Object.entries({

    key: 'value',

    keyTwo: 'valueTwo'

}))


序列化與反序列化

現(xiàn)在您可能會說普通對象和數(shù)組相對于映射和集合還有最后一個優(yōu)勢 — 序列化JSON.stringify()JSON.parse()。

但是,當我們使用時,有個第二個參數(shù)傳null: JSON.stringify(obj, null, 2) ,為什么呢?
它被稱為替換器,它允許我們定義任何自定義類型應(yīng)該如何序列化。所以,我們可以輕松的將Map進行序列化:

JSON.stringify(obj, (key, value) => {

  // Convert maps to plain objects

  if (value instanceof Map) {

    return Object.fromEntries(value)

  }

  return value

})


我們還可以用相反的方式將對象轉(zhuǎn)回Map:

JSON.parse(string, (key, value) => {

  if (value && typeof value === 'object') {

    return new Map(Object.entries(value))

  }

  return value

})



查看原文



該文章在 2023/10/25 15:18:57 編輯過
關(guān)鍵字查詢
相關(guān)文章
正在查詢...
點晴ERP是一款針對中小制造業(yè)的專業(yè)生產(chǎn)管理軟件系統(tǒng),系統(tǒng)成熟度和易用性得到了國內(nèi)大量中小企業(yè)的青睞。
點晴PMS碼頭管理系統(tǒng)主要針對港口碼頭集裝箱與散貨日常運作、調(diào)度、堆場、車隊、財務(wù)費用、相關(guān)報表等業(yè)務(wù)管理,結(jié)合碼頭的業(yè)務(wù)特點,圍繞調(diào)度、堆場作業(yè)而開發(fā)的。集技術(shù)的先進性、管理的有效性于一體,是物流碼頭及其他港口類企業(yè)的高效ERP管理信息系統(tǒng)。
點晴WMS倉儲管理系統(tǒng)提供了貨物產(chǎn)品管理,銷售管理,采購管理,倉儲管理,倉庫管理,保質(zhì)期管理,貨位管理,庫位管理,生產(chǎn)管理,WMS管理系統(tǒng),標簽打印,條形碼,二維碼管理,批號管理軟件。
點晴免費OA是一款軟件和通用服務(wù)都免費,不限功能、不限時間、不限用戶的免費OA協(xié)同辦公管理系統(tǒng)。
Copyright 2010-2025 ClickSun All Rights Reserved