오늘은 JavaScript Map 객체에 대해 알아보도록 하겠습니다. Map 객체는 키-값 쌍을 저장하며 각 쌍의 삽입 순서도 기억하는 Collection입니다. 요소의 삽입 순서를 기억하기 때문에 for...of 반복문을 사용할 때, 삽입 순서대로 원소를 순회할 수 있습니다. for...of 반복문을 순회하며 [key, value]로 이루어진 배열을 반환입니다.
let myMap = new Map()
let keyString = '문자열'
let keyObj = {}
let keyFunc = function() {}
// 값 설정
myMap.set(keyString, "'문자열'과 관련된 값")
myMap.set(keyObj, 'keyObj와 관련된 값')
myMap.set(keyFunc, 'keyFunc와 관련된 값')
console.log(myMap.size); // 3
// getting the values
console.log(myMap.get(keyString)); // "'문자열'과 관련된 값"
console.log(myMap.get(keyObj)); // "keyObj와 관련된 값"
console.log(myMap.get(keyFunc)); // "keyFunc와 관련된 값"
console.log(myMap.get('문자열')); // "'문자열'과 관련된 값"
// keyString === '문자열'이기 때문
console.log(myMap.get({})); // undefined, keyObj !== {}
console.log(myMap.get(function() {})); // undefined, keyFunc !== function () {}
key에 대한 비교를 '===' 연산자를 사용한다고 생각하면 됩니다. 그렇기 때문에 처음 3번의 get의 결과는 제대로 나왔습니다. 4번째 get에는 '문자열'이라는 키를 제공했습니다. keyString === '문자열'은 true이기 때문에 '문자열'과 관련된 값이라는 출력의 결과를 확인할 수 있습니다. 그렇다면 나머지 두 개의 결과는 왜 undefined일까요? keyObj와 keyFunc에는 객체를 만들고 함수를 만들 때 생겨난 레퍼런스가 저장되어 있기 때문에 같지 않는 것입니다. '===' 연산자 비교를 해도 true가 나오지 않습니다.
Map의 키로 NaN 사용하기
let myMap = new Map()
myMap.set(NaN, 'not a number')
console.log(myMap.get(NaN));
// "not a number"
let otherNaN = Number('foo')
console.log(myMap.get(otherNaN));
// "not a number"
NaN === NaN 의 결과는 false입니다. 그래서 ===의 결과로 key를 판단한다면 무조건 false가 나올 수 밖에 없습니다. 그렇기 때문에 NaN의 경우 자기 자신과 동일하지 않지만 키로서 사용할 수 있도록 NaN 키를 허용해줍니다.
for...of로 Map 순회하기
let myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
for (let [key, value] of myMap) {
console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
for (let key of myMap.keys()) {
console.log(key)
}
// 0
// 1
for (let value of myMap.values()) {
console.log(value)
}
// zero
// one
for (let [key, value] of myMap.entries()) {
console.log(key + ' = ' + value)
}
// 0 = zero
// 1 = one
for...of 구문을 이용하여 요소 순회가 가능합니다. 위에서는 총 4번을 순회해봤는데, 모두 삽입 순서대로 출력되는 것을 확인 할 수 있습니다.
forEach()로 Map 순회하기
let myMap = new Map()
myMap.set(0, 'zero')
myMap.set(1, 'one')
myMap.forEach(function(value, key) {
console.log(key + ' = ' + value)
})
// 0 = zero
// 1 = one
forEach 메서드로 순회도 가능합니다.
Array 객체와의 관계
let kvArray = [['key1', 'value1'], ['key2', 'value2']]
// Use the regular Map constructor to transform a 2D key-value Array into a map
let myMap = new Map(kvArray)
console.log(myMap.get('key1')) // returns "value1"
// Use Array.from() to transform a map into a 2D key-value Array
console.log(Array.from(myMap)) // Will show you exactly the same Array as kvArray
// A succinct way to do the same, using the spread syntax
console.log([...myMap])
// Or use the keys() or values() iterators, and convert them to an array
console.log(Array.from(myMap.keys())) // ["key1", "key2"]
먼저 키-쌍으로 구성된 2차원 배열을 이용하여 Map 객체를 생성할 수 있습니다. 위 예제에서 kvArray를 이용하여 Map을 생성하고 key1을 이용하여 출력했는데, 잘 나온 것을 확인할 수 있습니다. 그리고 Array.from 메서드를 이용하면 키-쌍으로 구성된 2차원 배열로 반환할 수도 있습니다. Spread 문법을 이용하면 동일한 결과를 받을 수도 있습니다. keys() 또는 values() 메서드를 이용하여 배열을 생성할 수도 있습니다.
참고:
developer.mozilla.org/ko/docs/Web/JavaScript/Reference/Global_Objects/Map
'JavaScript' 카테고리의 다른 글
[ES6 JavaScript] WeakMap (0) | 2020.10.13 |
---|---|
[ES6 JavaScript] Set (0) | 2020.10.11 |
[ES6 JavaScript] Generator (0) | 2020.10.07 |
[ES6 JavaScript] for...of (0) | 2020.10.06 |
[ES6 JavaScript] let, const (0) | 2020.10.05 |