JavaScript Object과 Map의 공통점과 차이
JavaScript의 Map과 Object는 Key-Value 쌍으로 동작한다는 점에서는 비슷하지만 다른 점이 많다. 공부하면서 이 부분이 많이 헷갈려서 이번 글에서는 이 둘의 차이가 무엇인지에 대해 다뤄보고 어떤 때 Object를 써야 하고 어떤 때 Map을 써야하는지 살펴보고자 한다.
Object과 Map의 공통점
Map과 Object의 값에 접근하기 위한 시간 복잡도
먼저 내가 제일 궁금했던 점은 Map과 Object의 값에 접근하기 위해서는 Key를 사용해야 하는데 이때 시간 복잡도가 다른가 하는 점이었다.
알아본 결과 N개의 원소가 있는 Map과 Object의 값의 접근을 위한 시간 복잡도는 O(1)로 같다. 물론 해싱 값이 모두 같은 값은 반환한다면 최대 O(N)이 되겠지만 이상한 해싱 함수를 사용하지 않는 이상 이런 일은 일어나지 않는다.
Object | Map | |
시간 복잡도 | O(1) | O(1) |
따라서 둘의 시간 복잡도는 같다고 봐도 무방하다.
Object과 Map의 차이점
값에 접근하기 위한 방법
Object는 [Key]을 사용하거나 .Key 를 사용해 값에 접근 할 수 있다. 하지만 .get(Key)를 사용하는 것은 구현되지 않은 함수를 사용하는 것이기 때문에 TypeError가 생기게 된다.
const blog = {
name: "Dev World",
author: "Dev Cho",
totalPosts: 350
}
console.log(blog.name); // Dev World
console.log(blog["name"]); // Dev World
console.log(blog.get("name")); // TypeError: blog.get is not a function
Map은 값에 접근하기 위해 get만을 사용해야 한다. [Key]을 사용하거나 .Key 를 사용해 값에 접근할 수 없다. 만약 이 둘을 쓰면 undefined 오류가 생기게 된다.
const blog = new Map([
["name", "Dev World"],
["author", "Dev Cho"],
["total posts", 350]
]);
console.log(blog.get("name")); // Dev World
console.log(blog.name); // undefined
console.log(blog["name"]); // undefined
Object | Map | |
.get(Key) | X | O |
.Key | O | X |
[Key] | O | X |
Key의 타입
여기서 궁금증이 생긴게 그러면 Key의 타입은 어떤가 하는 것이었다. Object는 Key 의 타입이 무조건 String으로만 만들어진다는 것을 아래 글에서 정리했었다.
Map은 아래 글에서 Key의 타입이 any로 생성자가 있다는 것을 알았다. 그런데 지금까지 String으로만 Key를 생성했기에 한 번 다른 값으로 생성해보기로 했다.
그 결과 Map에서는 String 뿐만 아니라 Int 등 다양한 타입으로 Key를 설정할 수 있다는 것을 알았다.
const blog = new Map([
[0, "Dev World"],
["author", "Dev Cho"],
["total posts", 350]
]);
console.log(blog.get(0)); // Dev World
따라서 이를 정리하면 다음과 같다.
Object | Map | |
Key의 타입 | String | Any |
원소의 입력 순서에 따른 출력 순서
Object는 원소의 입력 순서에 따라 출력 순서가 보장되지 않지만, Map은 입력 순서가 보장된다고 한다. 때문에 순서가 중요하면 Map을 써야 한다.
*나의 머신에서는 둘다 순서가 똑같이 나와서 예제를 추가하지 못했다. 아마도 런타임 환경에 따라 다른 것으로 보인다.
Object | Map | |
순서 보장 | X | O |
Iterator Interface 구현 여부 : forEach 사용 가능 여부
JavaScript에서 함수형으로 코딩을 하게 되면 forEach를 만이 사용하게 될 텐데 Object는 forEach를 지원하지 않는다. 따라서 아래와 같이 for문을 사용해 내부의 원소들에 접근해야 한다.
const blog = {
name: "Dev World",
author: "Dev Cho",
totalPosts: 350
}
for (const key in blog) {
console.log(key + ": " + blog[key]);
}
// name: Dev World
// author: Dev Cho
// totalPosts: 350
반면 Map은 내부에서 Iterator 인터페이스를 구현했기 때문에 forEach 사용이 가능하다.
const blog = new Map([
["name", "Dev World"],
["author", "Dev Cho"],
["total posts", 350]
]);
blog.forEach(callbackfn = (value, key, map) => {
console.log(`${key}: ${value}`)
})
// name: Dev World
// author: Dev Cho
// totalPosts: 350
Object | Map | |
Iterator 구현 (forEach 사용 가능) |
X | O |
정리
이번 글에서는 JavaScript의 Object와 Map의 차이에 대해 살펴보았다. 이를 총 정리하면 다음 표와 같이 정리가 가능하다. Map이 Object에 비해 순서가 일관되고 확장성이 있는 것을 알 수 있다.
다만 Key-Value 쌍을 저장하기 위한 객체로만 접근한다면 둘 사이에 성능 차이는 없다는 점을 명심하자.
Object | Map | |
시간 복잡도 | O(1) | O(1) |
.get(Key) | X | O |
.Key | O | X |
[Key] | O | X |
Key의 타입 | String | Any |
순서 보장 | X | O |
Iterator 구현 | X | O |