본문 바로가기
Script/JavaScript

[JavaScript] Chapter 34. 맵 객체(Map Object)

by song.ift 2023. 1. 16.

자바스크립트로 앱을 개발할 때 꼭 사용하는 자료형이 바로 객체(Object)다.

값을 키와 값으로 묶어 저장하고 조회하는 기능은 어떤 앱을 개발할 때나 쓰게 되는 경우가 많다.

이번 포스팅에서는 자바스크립트 객체를 좀 더 뺀-씨하게 사용할 수 있는 ES6 문법인 맵 객체에 대해 알아보려 한다.

 

맵 객체 메소드

맵 객체는 기존 객체와는 다르게 메소드만을 이용해 값을 넣고 뺀다.

기본적으로 삽입, 조회, 삭제를 할 수 있는 메소드들은 다음과 같다.

let max = new Map();

// set으로 맵 객체에 삽입
max.set('id', 0);
max.set('이름', '마이클');
max.set('전공', '영문학');
max.set('나이', 25);

// 이차원 배열로 넘겨주는 것도 가능
let michael = new Map([
  ['id', 0],
  ['이름', '마이클'],
  ['전공', '영문학'],
  ['나이', 29],
]);

// get으로 맵 객체 조회
max.get('이름'); // "마이클"

// delete로 삭제
max.delete('나이'); // 삭제가 성공하면 true를 반환

// clear로 맵 안의 프로퍼티 전부삭제
max.clear();

이외에도 다른 메소드를 쓸 수 있다.

객체의 메소드가 매우 제한적인것에 반해, 맵 객체는 풍부한 메소드를 제공하고 있다.

 

맵 객체의 장점

1. 문자열 아닌 값도 키로 사용 가능

객체에서는 문자열(String) 혹은 심볼(Symbol)만 프로퍼티의 키로 사용할 수 있었다.

맵 객체에서는 함수나 객체를 포함한 모든 자료형이 프로퍼티의 키로 쓰일 수 있다.

종종 키가 문자열이 아니라 숫자(Number)일 때 보기 더 편한 경우가 있다. 가령 오류코드에 따라 출력하는 메시지에 대한 정보를 가지고 있는 객체와 맵 객체를 생각해 본다하면.

const errorMessageObj = {
  404 : "페이지가 없습니다",
  500 : "서버 오류입니다",
  401 : "권한이 없습니다"
};

const errorMessageMap = new Map([
  [404, "페이지가 없습니다"],
  [500, "서버 오류입니다"],
  [401, "권한이 없습니다"],
]);

errorMessageObj.404  // unexpected number 에러
errorMessageObj["404"]  // '페이지가 없습니다'
errorMessageMap.get(404)  // '페이지가 없습니다'

객체의 경우는 문자열을 통해서만 조회가 가능하고,  "." 뒤에 숫자를 입력하면 에러가 난다.

하지만 맵 객체에서는 get메소드의 인자로 숫자를 넘겨줘도 제대로 값을 찾아오는 것을 볼 수 있다.

2. 메소드 사용의 명확성

일단 맵 객체를 다룰 때는 객체처럼 .이나 []로 접근할 필요 없이 메소드만으로 맵 객체 안에 들어있는 프로퍼티들을 수정하거나 조회할 수 있다. 메소드의 이름들(set, get, delete, clear)이 맵 객체를 어떻게 할지를 잘 나타내주고 있어, 객체보다 동작과 의도를 더 정확하게 보여준다고 할 수 있다.

let maxInfoObj = {
  name: '김맥스',
  age: 25,
  major: '영문학',
};

const maxInfoMap = new Map([
  ['name', '김맥스'],
  ['age', 25],
  ['major', '영문학'],
]);

// 객체 : let으로 선언해 빈 객체 할당해서 빈 객체로 초기화
maxInfoObj = {};

// 맵 객체 : clear 메소드 사용해 빈 맵 객체로 초기화
maxInfoMap.clear();

특히 맵의 프로퍼티를 명시적으로 지울 수 있는 clear나 delete같은 메소드를 제공하는게 인상적이다.

객체의 경우처럼 삭제시 빈 객체를 할당하는 것 보다 개발자의 의도를 명확히 드러낸다고 할 수 있다.

3. 깔끔한 순회

맵 객체는 그 자체로 for..of 문을 통해 순회가 가능하다. 이때 순회는 맵 이터레이터의 형태로 이루어진다.

맵 이터레이터는 키-값을 쌍으로 묶은 배열이다. entries메소드로 맵 이터레이터를 확인할 수 있다.

const maxInfoMap = new Map([
  ['name', '김맥스'],
  ['age', 25],
  ['major', '영문학'],
]);

maxInfoMap.entries();  // MapIterator { ["name", "김맥스"],["age", 25],["major", "영문학"]}

for (const [key, value] of maxInfoMap) {
  console.log(key, value);
}
// 결과
// "name" "김맥스"
// "age" 25
// "major" "영문학"

객체는 for...in 문이나 Object.keys를 사용하여 순회해 왔다.

저 두 가지 순회 방법은 기본적으로 객체 프로퍼티의 키 만을 순회하기 때문에, 그 키를 이용해서 객체의 값을 다시 얻어내야 한다.

(그런 불편함 때문에 ES2017에 Object.entries 가 등장하게 되었다. 이 메소드는 맵 객체처럼 키-값을 쌍으로 묶은 이터레이터를 반환한다.)

const maxInfoObj = {
  name: '김맥스',
  age: 25,
  major: '영문학',
};

// for in문 이용
for (key in maxInfoObj) {
  console.log(key, maxInfoObj[key]);
}

// Object.keys() 이용
for (key of Object.keys(maxInfoObj)) {
  console.log(key, maxinfoObj[key]);
}

 

언제 써야 할까

맵 객체는 객체의 프로퍼티를 자주 변경해야할 때 빛을 발한다.

메소드 이름들이 예측 가능하여 동작이 명확하고, 기존 객체와 달리 순회도 쉽게 이루어져 데이터를 조작하기 적합한 것 같다.

물론 모든 상황에 맵 객체를 쓸 필요는 없고, 자주 변경하지 않는 정보들은 객체에 저장해도 무방할 것 같다.

댓글