자바스크립트 맵 객체(Map Object)

JS의 맵 객체를 소개합니다., 2020.03.29

자바스크립트로 앱을 개발할 때 꼭 사용하는 자료형이 바로 객체(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();

이외에도 다른 메소드를 쓸 수 있습니다. 객체의 메소드가 매우 제한적인것에 반해, 맵 객체는 풍부한 메소드를 제공하고 있습니다. 맵 객체의 다른 메소드는 여기를 참조하세요!

맵 객체의 장점

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

객체에서는 문자열(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메소드의 인자로 숫자를 넘겨줘도 제대로 값을 찾아오는 것을 보실 수 있습니다.

메소드 사용의 명확성

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

let maxInfoObj = { name: '김맥스', age: 25, major: '영문학', }; const maxInfoMap = new Map([ ['name', '김맥스'], ['age', 25], ['major', '영문학'], ]); // 객체 : let으로 선언해 빈 객체 할당해서 빈 객체로 초기화 maxInfoObj = {}; // 맵 객체 : clear 메소드 사용해 빈 맵 객체로 초기화 maxInfoMap.clear();

특히 맵의 프로퍼티를 명시적으로 지울 수 있는 cleardelete같은 메소드를 제공하는게 인상적입니다. 객체의 경우처럼 삭제시 빈 객체를 할당하는 것 보다 개발자의 의도를 명확히 드러낸다고 할 수 있습니다.

깔끔한 순회

맵 객체는 그 자체로 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]); }

언제 써야 할까

맵 객체는 객체의 프로퍼티를 자주 변경해야할 때 빛을 발합니다. 메소드 이름들이 예측 가능하여 동작이 명확하고, 기존 객체와 달리 순회도 쉽게 이루어져 데이터를 조작하기 적합한 것 같습니다. 물론 모든 상황에 맵 객체를 쓸 필요는 없고, 자주 변경하지 않는 정보들은 객체에 저장해도 무방할 것 같습니다.

Reference


Written by 김맥스