Object.keys(obj).length
MDN 문서에서는 다음과 같이 설명한다.
실행 시까지 키를 알수 없고, 모든 키가 동일한 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' }
*/