[Map/Object] Map과 Object의 key, value 다루기 및 차이점
key - value 를 이용한 데이터 저장 방법은 두 가지가 있다.
- map
- object
이 두 가지가 같은 것이라고 생각했다.
그러던 중 두 개념이 다른 것임을 깨닫고 어떻게 다른지 찾아보았다.
더불어 데이터를 저장하고 사용하는 과정에서 벌어질 수 있는 다양한 상황을 실험해보았다.
이렇게 다른데 왜 같은 거라고 생각했을까?
실제로는 map을 잘 안써서 그런가
- 기본 개념 / 문법
Map | Object | |
생성 방법 | const map = new Map([ ["a", "문자형 key"], [1, "숫자 key"], [[1, 2, 3], "직접 array key"], [arr, "참조 array key"], ]); |
const object = { a: "문자형 key", 1: "숫자 key", "[1, 2, 3]": "직접 array key", }; |
new Map([[key, value], [key, value]...]) | {key:value, key, value...} | |
새로운 쌍 추가 | map.set(key, value) | object.key = value |
동일한 key 값이 있다면 value가 변경됨 | ||
key 종류 | 상관없음 - 다만, 직접 ["a",...] 같은 arr를 넣으면 value를 변경할수도 사용할 수도 없음 - 형식에 구애받지 않기 때문에 문자형을 넣을 때 ""처리를 하지 않는다면 오류가 발생 |
문자형 - 숫자도 넣을 수 있으나 자동 문자형으로 변형됨 - arr도 넣을 수 있으나 문자형으로 변환해서 넣어야 함 - 따로 ""처리를 하지 않아도 문자형으로 인식 |
value 꺼내기 | map.get(key) | object.key / object[key] - 만약 숫자 key라면 .을 사용할 수 없음 |
- 다른 점은 아래와 같다.
차이점 | map | object |
key 종류 | 상관없음 | string / symbol |
순서 | 순서있음 : 반복할 때 순서대로 반복 | 순서없음 |
정렬 | 삽입순으로 정렬 | 정렬 안 함 |
크기 추적 | 비교적 쉬움(map.size) > 시간복잡도 O(1) |
수동으로 추적해야 함 (Object.keys(object).length) > 시간복잡도 O(n) |
반복 | - for ... of 사용 가능 - forEach 사용 가능 |
- Object.keys(object).forEach((key) => {...}) - for ... in 사용 가능 |
장점 | - 비교적 느리다 - 거대한 데이터를 저장할 때 좋다 - 순서를 보존한다. - 잦은 추가/삭제작업을 할 때 좋다. |
- 비교적 빠르다(훨씬?) - JSON을 지원한다. - 데이터 저장을 위한 간단한 구조 - 기본 오브젝트를 생성하는데 훨씬 적은 시간이 걸림 - 별도의 로직이 적용되어야 하는 경우 |
단점 | - JSON을 사용할 수 없다. | - 반복하기 어렵다. |
map 실험
1. 맵에 .key 호출방식은 error는 나지 않으나 실행되지도 않는다.
2. 맵에 [key] 호출방식은 error가 난다.
3. 직접 array를 key로 넣은 경우 value를 get할 수 없다.
4. 밖에서 array를 만들어 key로 넣은 경우 value를 get할 수 있다.
5. function을 value로 넣을 수 있다.
> 아마 4, 5번은 JS의 저장 방식 때문이라고 생각한다. 불변성을 검색하다보면 이유를 알 수 있을 것 같다.
6. 직접 array를 key로 넣은 경우 value를 바꿀 수 있다. 동일한 키값이라면 set을 했을 때 value가 교체된다.
7. 밖에서 array를 만들어 key로 넣은 경우 value를 바꿀 수 있다. 다만 그냥 추가된다.
8. 직접 array를 만들어 넣은 경우 빼거나 변경은 불가하지만 map을 들여다보면 존재하긴 한다.
9. function이 value인 상황에서 get을 할당하면 함수로 사용 할 수 있다. 다만, 이렇게 쓰는 사람이 있을까?
Object 실험
1. key를 숫자로 입력했다면 []로만 value를 가지고 올 수 있다.
2. key를 문자형으로 입력했다면 []로 호출할 때 ""처리를 해주어야 한다.
3. key를 숫자로 입력했다면 [] 안에 숫자형으로 쓰든, 문자형으로 쓰든 상관없다.
4. [] 안에 arr형태를 입력했다면 오류는 나지 않으나 value는 가지고 올 수 없다.
5. 문자형이라면 []가 내용이어도 상관없다.
6. 객체 안에서 value로 바로 함수를 만들 수 있다.
7. 외부에 있는 변수를 key값으로 입력해도 그건 그냥 문자형으로 입력되어 외부 변수와 상관 없어진다.
8. value로는 외부 변수(array, function...)를 가지고 올 수 있다.
실험코드
// Part.1
const aFunction = () => {
console.log("hi");
};
const arr = [1, 2, 3];
const map = new Map([
["a", "문자형 key"],
[1, "숫자 key"],
[[1, 2, 3], "직접 array key"],
[arr, "참조 array key"],
["function", aFunction],
]);
console.log("map.a: ", map.a);
console.log("map.get('a'): ", map.get("a"));
console.log("map.get('[1, 2, 3]'): ", map.get("[1,2,3]"));
console.log("map.get(arr): ", map.get(arr));
console.log("map.get('function'): ", map.get("function"));
console.log(map[a]); // error
// Part.2
map.set(arr, "value 바꾸기");
map.set([1, 2, 3], "value 바꾸기");
console.log("map.get('[1, 2, 3]'): ", map.get("[1,2,3]"));
console.log("map.get(arr): ", map.get(arr));
console.log(...map);
const bFunction = map.get("function");
console.log(bFunction);
bFunction();
// Part.3
const arr = [1, 2, 3];
const outsideFunction = () => {
console.log("hi");
};
const object = {
a: "문자형 key",
1: "숫자 key",
"[1, 2, 3]": "직접 array key",
function: () => {
console.log("hi");
},
arr: "외부 array key",
outsideArray: arr,
outsideFunction: outsideFunction,
};
console.log("object.a = ", object.a);
// console.log(object[a]); //error
console.log("object['a'] = ", object["a"]);
// console.log(object.1); //error
console.log("object[1] = ", object[1]);
console.log('object["1"] = ', object["1"]);
// console.log(object.[1, 2, 3]); //error
console.log("object[[1, 2, 3]] = ", object[[1, 2, 3]]);
console.log("object['[1, 2, 3]'] = ", object["[1, 2, 3]"]);
console.log("object.function", object.function);
// console.log(object[function]); //error
console.log('object["function"] = ', object["function"]);
console.log("object[arr] = ", object["arr"]);
console.log("object.arr = ", object.arr);
console.log("object.outsideArray = ", object.outsideArray);
console.log("object.outsideFunction = ", object.outsideFunction);
참고 사이트
map이 더 낫다는 글:
https://shanepark.tistory.com/220
제발 한국인이라면 자바스크립트 Object를 Map 처럼 사용하지 맙시다.
Photo by Steve Johnson on Unsplash Introduction 오늘 코딩하던 중에 Javascript 에서 만든 Map을 Controller 쪽으로 어떻게 넘길지에 대해 고민 하는 일이 있었습니다. JavaScript 에서는 Object 를 사용하면 왠만하면
shanepark.tistory.com
object가 더 낫다는 글:
https://kim-born-in-mapo.tistory.com/26
[ES6] Map vs Object 비교 [번역]
Map 과 Object를 잘 비교해서 정리해놓은 글이 있어서 나름(?) 번역해서 정리해놓고자 합니다. [개념] Map 이란 무엇인가?: Map은 data collection 유형으로 ( 좀 더 있어보이게 말하면 - 추상적 데이터 구조
kim-born-in-mapo.tistory.com
기타 자료:
https://kellis.tistory.com/129
[ES6+] Map vs Object
이 글에서는 ES6에서 새롭게 도입된 Map에 대해서 알아보고, 이것이 Object Literal과는 무슨 차이가 있는지 살펴보도록 하겠습니다. (1) Map? Map은 대부분 개발자에게 익숙한 단어일 것입니다. ECMA Script
kellis.tistory.com
https://velog.io/@namda-on/JavaScript-Map-%EA%B3%BC-Object-%EC%9D%98-%EC%B0%A8%EC%9D%B4
JavaScript Map 과 Object 의 차이
Javascript에는 7개의 타입(ES6 기준으로)이 존재하는데 해당 타입들은 크게 원시타입과 객체 타입으로 분리된다. 원시타입booleannullundefinednumberstringsymbol객체타입 (object/reference type)object자바스크립트
velog.io