Map 오브젝트 -ECMAScript
Map
오브젝트는 Object
오브젝트와 비슷하지만,
다양한 타입을 프로퍼티 키로 사용할 수 있는 점이 다릅니다.
- Map 오브젝트
개요
Map
오브젝트는 key
와 value
로 구성됩니다.Object
오브젝트의 key
타입은 String
또는 Symbol
이지만
Map
오브젝트는 아무 객체와 원시값(Object
,Function
등등)이라도 key
와 value
로 사용할 수 있습니다.
key
와 value
값을 저장하며 각 쌍의 삽입 순서도 기억합니다.
Map
오브젝트는 key
, value
로 구성되지만 {key: value}형태로 작성하지 않고,[“key”, “value”]
와 같이 이터러블 형태로 작성합니다.
key에 다양한 타입을 작성할 수 있는 것과 이러터블 형태로 작성하는 것이
Map 오브젝트와 Object 오브젝트의 차이입니다.
Map
오브젝트는 key
값이 같으면 추가하지 않고 value
값이 대체되며 추가한 순서대로 읽습니다.
- 참고 용도 : Map 과 Object 차이 정리
(●’◡’●) | Map | Object |
---|---|---|
의도치 않은 key | Map은 명시적으로 제공한 키 외에는 어떤 키도 가지지 않습니다. | Object는 프로토타입을 가지므로 기본 키가 존재할 수 있습니다. 주의하지 않으면 직접 제공한 키와 충돌할 수도 있습니다. * 참고: ES5부터, 프로토타입으로 인한 키 충돌은 Object.create(null)로 해결할 수 있지만, 실제로 쓰이는 경우는 적습니다. |
key 타입 | Map의 key는 함수, 객체 등을 포함한 모든 값이 가능합니다. | Object의 키는 반드시 String 또는 Symbol이어야 합니다. |
key 정렬 | Map의 키는 정렬됩니다. 따라서 Map의 이터레이션은 삽입순으로 이뤄집니다. | Object의 키는 정렬되지 않습니다. * 참고: ECMAScript 2015 이후로, 객체도 문자열과 Symbol 키의 생성 순서를 유지합니다. ECMEScript 2015 명세를 준수하는 JavaScript 엔진에서 문자열 키만 가진 객체를 순회하면 삽입 순을 따라갑니다. |
크기 | Map의 항목 수는 size 속성을 통해 쉽게 알아낼 수 있습니다. | Object의 항목 수는 직접 알아내야 합니다. |
이터러블 | Map은 이터러블이므로, 바로 이터레이션할 수 있습니다. | Object를 순회하려면 먼저 모든 키를 알아낸 후, 그 키의 배열을 순회해야 합니다. |
성능 | 잦은 키-값 쌍의 추가와 제거에서 더 좋은 성능을 보입니다. | 키-값 쌍의 빈번한 추가 및 제거에 최적화되지 않았습니다. |
- Map 오브젝트가 편리하고 유용성이 높습니다. (그러나 모든 상황에 해당하지는 않습니다.)
Map 오브젝트는 컬렉션에서 효율이 높습니다. key, value 형태이고 이터러블일 때는 Map 오브젝트를 사용하고
값과 함수가 혼합된 형태면 Object 오브젝트를 사용하는 것이 좋습니다.
new Map(): Map 인스턴스 생성
Map 인스턴스를 생성하여 반환합니다.
new Map([iterable])
- iterable 선택적 파라미터
요소가 키-값 쌍인Array
또는 다른 순회 가능한 객체(예: [[1, ‘one’], [2, ‘two’]]).
각 키-값 쌍은 새로운Map
에 포함됩니다.
for-of
1 | let emptyMap = new Map(); |
emptyMap = new Map()
과 같이 파라미터를 작성하지 않고Map
인스턴스를 생성할 수 있습니다.[key, value]
가 없는 형태로 생성됩니다. 이는Map
오브젝트 메서드를 사용하여[key, value]
를 추가해줄 수 있습니다.
Map()
파라미터는 이터러블 오브젝트이어야 하므로 대괄호[]
를 작성하였으며, 그 안에[“key1”, “value1”]
형태로 작성하였습니다.key1
이key
가 되고value1
이value
가 됩니다.다음은 newMap 인스턴스 구조입니다.
__proto__:
Map
은new Map()
을 실행하면Map.prototype
에 연결된 프로퍼티로 인스턴스를 생성한다는 것을 암시합니다.0:
{“key1” => “sports”}
에서0
은 인덱스이며Map()
파라미터에 작성한 값이 아닙니다.Map
은 엔진이 파라미터의 이터러블 오브젝트에 작성한 순서로 인덱스를 부여합니다. 따라서 작성한 순서대로 읽을 수 있습니다.
for-of
문 출력 결과가[“key1”, “sports”]
,[“key2”, “value2”]
두 개만 표시된 이유는 첫 번째의“key1”
과 세 번째“key1”
이 같기 때문입니다.
이와 같이key
값이 같으면 추가되지 않고,value
값을 나중에 작성한 값으로 대체합니다.
인덱스를 부여하여 작성한 순서로 저장하더라도 key 값의 일치 여부를 체크 하기 때문에 첫 번째의 value값을 세 번째의 value 값으로 대체하고 세 번째를 추가하지 않습니다.
forEach()
1 | let newMap = new Map([ |
Map()
파라미터에 이터러블 오브젝트를 작성하고, 그 안에 두 개의[key, value]
를 작성했습니다.for-of
문을 반복하면element
변수에[“key1”, “value1”]
형태로 설정됩니다.배열 형태이므로
for.Each()
메서드를 사용할 수 있습니다.for.Each()
가[“key1”, “value1”]
형태를
첫 번째로 읽으면for.Each()
의keyValue
파라미터에“key1”
이 설정되고index
에0
이 설정됩니다.두 번째를 읽으면
keyValue
파라미터에“value1”
이 설정되고index
에1
이 설정됩니다.
for-of
문을 처음 반복하면[“key1”, “value1”]
이 읽힙니다.
이때“key1”
이for-of
문의[key, value]
에서key
에 설정되고“value1”
이value
에 설정됩니다.
key
, value
가 모두 설정되므로 앞 코드와 같이 forEach()
로 배열을 전개하지 않아도 됩니다.
Error
1 | 1. try { |
Map()
파라미터에 이터러블 오브젝트를 작성하고 그 안에 배열로 엘리먼트를 작성합니다.[“one”, 1]
에서 대괄호[]
가 이터러블이므로 이를 제외하면“one”
,1
형태가 되어 에러가 발생합니다.[[“one”, 1]]
형태로 작성해야 합니다.
Map()
파라미터에 key,value를 작성하지만,{key: value}
형태로 작성할 수 없으며TypeError
가 발생합니다.[[“one”, 1]]
형태로 작성해야 합니다.
Map()
파라미터에 대괄호[]
를 작성하고, 그 안에{one: 1}
형태로 작성하면 에러가 발생하지 않고Map
인스턴스가 생성됩니다. 하지만 실행 결과에서 볼 수 있듯이key,value
에 값이 설정되지 않아undefined
가 출력됩니다.
set(): key와 value 설정
set()
메서드는 Map
오브젝트에서 주어진 key
를 가진 엘리먼트를 추가하고, key
에 엘리먼트가 이미 있다면 대체합니다.
Map.prototype.set(key, value)
첫 번째 파라미터에 key
가 될 String
또는 오브젝트를 작성하고 두 번째 파라미터에 value
를 작성합니다.set()
을 실행한 후 Map
인스턴스를 반환하므로 메서드 체인(method chain
)형태로 계속해서 Map
인스턴스의 메서드를 호출할 수 있습니다.
1 | 1. const newMap = new Map(); |
new Map()
파라미터를 작성하지 않고 인스턴스를 생성했습니다.
인스턴스에key
,value
를 추가할 수는 있으나 인스턴스를 삭제할 수는 없습니다.
newMap.set()
으로newMap
인스턴스에[key, value]
값을 추가합니다.“one”
이 키가 되고100
이value
가 됩니다.
size
프로퍼티는Map
인스턴스의 엘리먼트 수를 반환합니다. 이 값은 바꿀 수 없습니다. 바꾸면TypeError
가 발생합니다.
set()
의 첫 번째 파라미터에Object {}
가key
가 되고, 두 번째 파라미터인“오브젝트”
가value
가 됩니다.
set()
의 첫 번째 파라미터인function
오브젝트가key
가 되고 두 번째 파라미터인“Function”
이value
가 됩니다.
- 첫 번째 파라미터인
Number
인스턴스가key
가 되고, 두 번째 파라미터인“인스턴스”
가value
가 됩니다.
- 첫 번째 파라미터인
NaN
이key
가 되고, 두 번째 파라미터인“Not a Number”
가value
가 됩니다.NaN
을key
로 사용할 수 있습니다.
newMap
인스턴스를for-of
문으로 반복하면 추가한 순서대로 전개됩니다.newMap의 인스턴스 구조
Map(5)
[[Entries]]
0: {“one” => 100}
1: {Object => “오브젝트”}
2: {function(){} => “Function”}
3: {Number => “인스턴스”}
4: {NaN => “Not a Number”}
1 | const newMap = new Map(); |
newMap
인스턴스에“one”
을key
로 하여100
을 설정한 후, 다시“one”
을key
로 하여123
을 설정하면key
값이 같으므로100
이123
으로 대체됩니다.
set()
의 첫 번째 파라미터에Object
오브젝트를 직접 작성하지 않고 별도로 작성한sportsObj
오브젝트를 지정했습니다.sportsObj
가 key가 되고“Sports Object”
가 value가 됩니다.
sportsObj key
가 존재하므로value
가 대체됩니다.
set()
의 첫 번째 파라미터에Object 리터럴 {}
을 지정했습니다.Object
오브젝트를 생성하여 메모리에 저장하고newMap
인스턴스에key
로 사용하여“Object-1”
을 추가합니다.
set()
의 첫 번째 파라미터에Object
리터럴을 지정해도 앞의key
값과 중복되지 않습니다.
왜냐하면 첫 번째 파라미터의Object
리터럴이 새로운Object
오브젝트를 생성하므로
앞의 코드와 다른 메모리 주소에 저장되기 때문입니다.
앞의Object
오브젝트가 저장된 메모리 주소와 생성한Object
오브젝트의 메모리 주소가 다르므로value
가 대체되지 않고 추가됩니다.
get(): key가 같은 value 반환
Map
인스턴스에서 key
값이 같은 value
를 반환합니다.
Map.prototype.get(key)
파라미터에 검색할 key
값을 작성합니다. 파라미터의 key
가 Map
인스턴스에 존재하면 value
를 반환하고, 존재하지 않으면 undefined
를 반환합니다. key
의 값 타입까지 체크합니다 (123 와 “123”은 같지 않습니다.)
1 | const newMap = new Map(); |
set()
을 실행하면[“one”, 100]
형태로 등록됩니다.get()
파라미터에 검색할key
값을 작성합니다.“one”
이newMap
인스턴스에 존재하므로value
인100
을 반환합니다.
get()
의 파라미터 값인“two”
가newMap
인스턴스key
에 존재하지 않으므로undefined
입니다.
set()
의 첫 번째 파라미터에sportsObj
의 메모리 주소를key
로 지정하여newMap
인스턴스에 추가합니다.
다시sportsObj
의 메모리 주소를 파라미터 값으로 지정하여get()
을 수행하므로“Sports Object”
가 반환됩니다.
1 | const newMap = new Map(); |
set()
파라미터인Object
오브젝트와get()
파라미터인Object
오브젝트의 메모리 주소가 다름으로undefined를
반환합니다.
get(123)
으로 검색하면key
의 타입까지 체크하여value
를 반환합니다.get(“123”)
으로 값을 구하면 “123”이String
타입이므로 타입이 같지않습니다.undefined
가 반환됩니다.
set()
의 파라미터에NaN
을 지정하고get()
의 파라미터에NaN
을 지정하면key
값이 같으므로value
값을 반환합니다.ES5에서 (NaN === NaN) 비교 결과가 true가 아닌 문제가 있었지만 Map 오브젝트에 반영되었습니다.
has(): key 존재 여부
Map
인스턴스에서 key
값의 존재 여부를 반환합니다.
Map.prototype.has(key)
key
값이 존재하면 true
, 아니라면 false
를 반환합니다.
1 | const newMap = new Map(); |
key
를 비교한다는 점은get()
과 같습니다.get()
은 해당key
의value
를 반환.has()
는key
값 존재 여부를 체크,true/false
값을 반환합니다.
entries(): 이터레이터 오브젝트 생성
[key, value]
를 반환하는 이터레이터 오브젝트를 생성하여 반환합니다.
Map.prototype.entries()
생성한 이터레이터 오브젝트에 next()
를 호출하면 [key, value]
를 반환합니다.next()
를 호출할 때마다 Map
인스턴스에 추가한 순서대로 읽힙니다.
1 | const newMap = new Map([ |
new Map()
으로 두 개의 엘리먼트를 가진Map
인스턴스를 생성합니다.
생성한Map
인스턴스의entries()
를 호출하여 이터러블 오브젝트를 생성하고 반환합니다.
next()
를 호출하면 첫 번째의[“key1”, “value1”]
를{value: Array[2], done: false}
형태의value
에 설정하여 반환합니다.Array[2]
로 표시된 이유는[“key1”, “value1”]
형태이기 때문입니다.
keys(): key 반환 이터레이터 오브젝트 생성
key
값을 반환하는 이터레이터 오브젝트를 생성하여 반환합니다.
Map.prototype.keys()
생성한 이터레이터 오브젝트의 next()
를 호출하면 [key, value]
형태에서 key
값만 반환합니다.Map
인스턴스에 추가한 순서대로 읽힙니다.
1 | const newMap = new Map([ |
newMap.keys()
로key
값만 반환하는 이터레이터 오브젝트를 생성해iteratorObj
에 할당합니다.
next()
를 호출하면[“key1”, “value1”]
에서“key1”
을{value: “key1”, done:false}
형태로value
에 설정하여 반환합니다.
({}, “오브젝트”)
형태로 추가했으므로Object
오브젝트가key
가 됩니다.{value: Object, done: false}
형태가 반환됩니다.
values(): value 반환 이터레이터 오브젝트 생성
value
값을 반환하는 이터레이터 오브젝트를 생성하여 반환합니다.
Map.prototype.values()
생성한 이터레이터 오브젝트의 next()
를 호출하면 value
값 만 반환합니다.
1 | const newMap = new Map([ |
newMap.values()
로value
값을 반환하는 이터레이터 오브젝트를 생성하여 반환합니다.
next()
를 호출하면[“key1”, “value1”]
에서“value1”
을{value: “value1”, done: false}
의value
에 설정하여 반환합니다.
“오브젝트”
가value
가 됩니다.{value: “오브젝트”, done:false}
형태로 반환됩니다.
forEach(): 엘리먼트마다 콜백 함수 호출
Map
인스턴스를 반복할 때 마다 callback
함수를 호출합니다.
Map.prototype.forEach(function)
첫 번째 파라미터에 반복할 때마다 호출할 콜백 함수를 작성합니다.
두 번째 파라미터는 선택적 파라미터로 콜백 함수에서 this로 참조할 오브젝트를 지정합니다.
중요 포인트
forEach()
는 호출할 때마다 세 개의 파라미터를 넘겨줍니다.
[key, value]에서 value
[key, value]에서 key
실행 중인 Map 인스턴스
key, value 순서가 아닌 value, key 순서입니다.
1 | const newMap = new Map([ |
forEach()
가 처음 호출되면[“key1”, “value1”]
을 읽으며 파라미터value
에“value1”
이 설정되고 파라미터key
에“key1”
이 설정됩니다. 세 번째의map
파라미터에newMap
인스턴스가 설정됩니다.
두 번째 호출 역시 마찬가지로 설정됩니다.
delete(): 엘리먼트 삭제
Map
인스턴스에서 key
값이 같은 엘리먼트를 삭제합니다.
Map.prototype.delete(key)
파라미터에 삭제할 key
값을 지정합니다. Map
인스턴스에 같은 key
가 존재하면 엘리먼트를 삭제하고 true
를 반환합니다. key
값이 존재하지 않으면 false
를 반환합니다.
1 | const newMap = new Map([ |
delete()
파라미터에 작성한“key1”
이newMap
인스턴스에 존재하므로[“key1”, “value1”]
엘리먼트를 삭제하고true
를 반환합니다.
delete()
파라미터에 작성한Object
오브젝트{}가newMap
인스턴스에 존재하는 것처럼 보이지만,새로운Object
오브젝트를 생성하여 메모리에 저장하므로newMap
인스턴스에 저장된Object
오브젝트와 메모리 주소가 달라서 삭제하지 못합니다.false
가 반환됩니다.
delete()
파라미터의sportsObj
와newMap
인스턴스의sportsObj
가 같은 메모리 주소를 참조하므로 삭제가 되며true
를 반환합니다.
clear(): 모든 key, value 지움
Map
인스턴스의 모든 [key, value]
를 지웁니다.
Map.prototype.clear()
Map
인스턴스를 삭제하는 것이 아니라 [key, value]
만 지웁니다.
나중에 Map
인스턴스에 [key, value]
를 추가해 줄 수 있습니다.
1 | const newMap = new Map([ |
size
프로퍼티는newMap
인스턴스의[key, value]
엘리먼트 수를 반환합니다. 2가 출력됩니다.
clear()
는newMap
인스턴스의 모든[key, value]
를 지웁니다. 따라서size
값으로0
이 출력됩니다.
Symbol.iterator(): 이터레이터 오브젝트 생성
이터레이터 오브젝트를 생성하여 반환합니다.
Map.prototype.[Symbol.iterator]
생성한 이터레이터 오브젝트의 next()
를 호출하면 Map
인스턴스에 작성된 순서대로 [key, value]
를 반환합니다.
Map.prototype.entries()
와 같습니다.
1 | let newMap = new Map([ |
newMap
인스턴스의Symbol.iterator
를 호출하면 이터레이터 오브젝트를 생성하여 반환합니다.
next()
를 호출할 때마다[“1”, “music”]
과[“2”, “sports”]
를 순서대로 읽어{value: Array[2], done: false}
형태로 반환합니다.Array[2]
에 읽은[key, value]
가 설정됩니다.