Object.keys(obj).lengthMDN 문서에서는 다음과 같이 설명한다.
실행 시까지 키를 알수 없고, 모든 키가 동일한 type이며 모든 값들이 동일한 type일 경우에는 objects를 대신해서 map을 사용해라.
각 개별 요소에 대해 적용해야 하는 로직이 있을 경우에는 objects를 사용해라.
맵(Map)은 키가 있는 데이터를 저장한다는 점에서 객체와 유사하지만 맵은 키에 다양한 자료형을 허용한다는 점에서 차이가 있습니다.
맵에는 다음과 같은 주요 메서드와 프로퍼티가 있습니다.
new Map() – 맵을 만듭니다.map.set(key, value) – key를 이용해 value를 저장합니다.map.get(key) – key에 해당하는 값을 반환합니다. key가 존재하지 않으면 undefined를 반환합니다.map.has(key) – key가 존재하면 true, 존재하지 않으면 false를 반환합니다.map.delete(key) – key에 해당하는 값을 삭제합니다.map.clear() – 맵 안의 모든 요소를 제거합니다.map.size – 요소의 개수를 반환합니다.let map = new Map();
map.set("1", "1 String"); // 문자형 키
map.set(1, "1 Number"); // 숫자형 키
map.set(true, "1 Boolean"); // 불린형 키
// 객체는 키를 문자형으로 변환하지만
// 맵은 키의 타입을 변환시키지 않고 그대로 유지합니다. 따라서 아래의 코드는 출력되는 값이 다릅니다.
console.log(map.get(1)); // '1 Number'
console.log(map.get("1")); // '1 String'
console.log(map.get(true)); // '1 Boolean'
console.log(map.size); // 3
/*출력
1 Number
1 String
1 Boolean
3
*/
맵은 객체와 달리 키를 문자형으로 변환하지 않고, 키엔 자료형 제약이 없습니다.
🧨주의 사항
map[key]는Map을 쓰는 바른 방법이 아닙니다.
map[key] = 2로 값을 설정하는 것 같이map[key]를 사용할 수 있긴 합니다.
하지만 이 방법은map을 일반 객체처럼 취급하게 됩니다.
따라서 여러 제약이 생기기 때문에 map을 사용할 땐 map전용 메서드set,get등을 사용해야만 합니다.
map.set을 호출할 때마다 맵 자신이 반환됩니다.
이를 이용하여 map.set을 '체이닝(chaining)'할 수 있습니다.
map.set("1", "1 String").set(1, "1 Number").set(true, "1 Boolean");
console.log(map.get(1)); // '1 Number'
console.log(map.get("1")); // '1 String'
console.log(map.get(true)); // '1 Boolean'
console.log(map.size); // 3
/*출력
1 Number
1 String
1 Boolean
3
*/
let map = new Map();
map.set("1", "1 String").set(1, "1 Number").set(true, "1 Boolean");
console.log(map.size); // 3
console.log(map.has(1)); // true
console.log(map); // Map(3) { '1' => '1 String', 1 => '1 Number', true => '1 Boolean' }
console.log(map.delete(1)); // true
console.log(map.has(1)); // false
console.log(map); // Map(2) { '1' => '1 String', true => '1 Boolean' }
map.clear();
console.log(map); // Map(0) {}
/*
출력
3
true
Map(3) { '1' => '1 String', 1 => '1 Number', true => '1 Boolean' }
true
false
Map(2) { '1' => '1 String', true => '1 Boolean' }
Map(0) {}
*/
map.keys() – 각 요소의 키를 모은 반복 가능한(iterable, 이터러블) 객체를 반환합니다.map.values() – 각 요소의 값을 모은 이터러블 객체를 반환합니다.map.entries() – 요소의 [키, 값]을 한 쌍으로 하는 이터러블 객체를 반환합니다. 이 이터러블 객체는 for..of반복문의 기초로 쓰입니다.let map = new Map();
map.set("1", "1 String").set(1, "1 Number").set(true, "1 Boolean");
console.log(map.keys());
console.log(map.values());
console.log(map.entries());
for (let i of map.keys()) {
console.log(i);
}
for (let i of map.values()) {
console.log(i);
}
for (let i of map.entries()) {
console.log(i);
}
/* 출력
[Map Iterator] { '1', 1, true }
[Map Iterator] { '1 String', '1 Number', '1 Boolean' }
[Map Entries] {
[ '1', '1 String' ],
[ 1, '1 Number' ],
[ true, '1 Boolean' ]
}
1
1
true
1 String
1 Number
1 Boolean
[ '1', '1 String' ]
[ 1, '1 Number' ]
[ true, '1 Boolean' ]
*/
let map = new Map();
map.set("1", "1 String").set(1, "1 Number").set(true, "1 Boolean");
map.forEach((item, key) => console.log(`${key} : ${item}`));
/*
출력
1 : 1 String
1 : 1 Number
true : 1 Boolean
*/
평범한 객체를 가지고 맵을 만들고 싶다면 내장 메서드 Object.entries(obj)를 활용해서 객체의 키-값 쌍을 요소([key, value])로 가지는 배열로 만들어줍니다.
let obj = {
name: "John",
age: 30,
};
let map = new Map(Object.entries(obj));
console.log(map);
console.log(map.get("name"));
/*
출력
Map(2) { 'name' => 'John', 'age' => 30 }
John
*/
let map = new Map();
map.set("name", "Shin").set("age", "26").set(true, "1 Boolean");
//let obj = Object.fromEntries(map.entries()); // 아래와 같은 동작
let obj = Object.fromEntries(map);
console.log(obj);
/*
출력
{ name: 'Shin', age: '26', true: '1 Boolean' }
*/