只會用Object?我想推薦你試試Map
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
導(dǎo)讀 在 本文將介紹
為什么這與 可迭代性
對象對象的遍歷由于對象不能使用使用
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 } 可以看到 // 方法一:使用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ù)字,并不能直接進(jìn)行計算,例如 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如果是 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() 來做類似的事情,盡管它看起來不是那么流行,但確實(shí)可以 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 } 對于 // 你可以只便利values,keys for (const value of myMap.values()) { console.log(value) } for (const key of myMap.keys()) { console.log(key) } key內(nèi)置key當(dāng)我們這樣創(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的順序
const [[firstKey, firstValue]] = myMap 實(shí)現(xiàn)LRU緩存用此特性,我們可以實(shí)現(xiàn)一個
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中沒有該鍵,且已達(dá)到緩存容量上限 let oldestKey = this.map.keys().next().value; // 獲取Map中第一個(最久未使用)的鍵 this.map.delete(oldestKey); } this.map.set(key, value); // 將新的或更新的鍵值對插入到Map末尾,表示最近使用過 } } key的類型
myMap.set({}, value) myMap.set([], value) myMap.set(document.body, value) myMap.set(function() {}, value) myMap.set(myDog, value) 在 復(fù)制與轉(zhuǎn)換復(fù)制你可能會覺得對象更容易復(fù)制,比如: const copied = {...myObject} const copied = Object.assign({}, myObject) 但,實(shí)際上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' })) 序列化與反序列化
但是,當(dāng)我們使用時,有個第二個參數(shù)傳 JSON.stringify(obj, (key, value) => { // Convert maps to plain objects if (value instanceof Map) { return Object.fromEntries(value) } return value }) 我們還可以用相反的方式將對象轉(zhuǎn)回 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)文章
正在查詢... |