-
[ES6] Map vs Object 비교 [번역]맨땅에코딩/javascript 2020. 8. 7. 16:44
Map 과 Object를 잘 비교해서 정리해놓은 글이 있어서 나름(?) 번역해서 정리해놓고자 합니다.
[개념]
Map 이란 무엇인가?: Map은 data collection 유형으로 ( 좀 더 있어보이게 말하면 - 추상적 데이터 구조 유형) , 즉 데이터가 어떠한 쌍의 형태로 저장되어있는데, 유일한 key와 그 키에 연결된 value를 포함한다.각 저장된 key의 유일함 때문에 중복된 쌍은 없다.
Map은 빠른 검색과 데이터를 들여다보는 일에 주로 사용된다.
※ 중요한 점 : Map의 key와 value는 어떠한 데이터 유형으로도 가능하다. string 혹은 integer 로 제한되어있지 않다.
Object 란 무엇인가?: 모두들 Object를 알고 있다. 특히 Javascript안에서는. Object는 객체이다. 그렇지않은가? 맞다. 하지만 좀 더 설명이 필요하다.
Javascript에서 Regular Object ('regular'란 단에 주목하라) 는 dictionary type 이다.- 즉, Map 처럼 key-value의 저장방식을 따라간다는 의미다. - 혹은 우리는 보통 "property" 라고 칭한다.- 또한 유일하며 단일 value와 관련이 있다. 덧붙여 말하면, Javascript에서 Object는 내장형 prototype이다. Javascript에서 거의 모든 객체들은(Map을 포함해서)Object의 instance들이다.
따라서, 정의에 의하면, Object와 Map은 동일한 개념에 기반을 두었다. - 데이터 저장을 위해 key-value를 사용
하지만, 다른점은 존재한다. - 그들은 서로 정말 다르다. 주로..
- key 필드 : Object에서는, 보통의 사전형 규칙을 따른다. key는 반드시 - integer 혹은 string 혹은 symbols 같은 단순한 유형이어야 한다. 하지만 Map은 어떠한 데이터 유형도 가능하다.
- 요소 순서 : Map에서는, 원래의 요소들의 순서가 보존되지만 Object는 그렇지 않다.
- 상속관계 : Map은 Object의 instance지만 Object는 당연히 Map의 instance가 아니다.
var map = new Map([[1,2],[3,4]]); console.log(map instanceof Object); //true var obj = new Object(); console.log(obj instanceof Map); //false
[객체 생성 방법]
Object
: Array처럼, Object는 간단하다. 새로운 객체를 선언하려면 글자그대로의 방법을 사용한다.
var obj = {}; //Empty object var obj = {id: 1, name: "Test object"};
혹은 생성자를 사용
var obj = new Object(); //Empty Object var obj = new Object; //same result
혹은 Object.prototype.create 를 사용!
var obj = Object.create(null); //Empty Object
※ 알아둘 점 : Object.create를 매우 특정한 경우에만 사용할것,
- 생성자를 사용하지 않고 "상속"하는 방법
var Vehicle = { type: "General", display: function(){console.log(this.type);} } var Car = Object.create(Vehicle); //create a new Car inherits from Vehicle Car.type = "Car"; //overwrite the property Car.display();//"Car" Vehicle.display();//still "General"
※ Array처럼, 내장형 생성자를 통해 생성하지 않는다.
- 타이핑이 길어짐
- 낮은 성능
- 헷갈림 & 실수할 가능성이 많다. 예를 들어
var obj = new Object(id: 1, name: "test") //Error - obviously var obj1 = {id: 1, name: "test"}; var obj2 = new Object(obj1); //obj1 and obj2 points to the same one obj2.id = 2; console.log(obj1.id); //2
Map
Map은 생성 방법이 단 한가지다. 내장형 생성자와 new 지시어를 사용한다.
var map = new Map(); //Empty Map var map = new Map([[1,2],[2,3]]); // map = {1=>2, 2=>3}
Map([iterable])
: 생성자는 배열 혹은 key-value 쌍으로 된 요소들인 배열 혹은 iterable 객체를 인자로 받는다.
[요소에 접근하기]
- Map은 Map.prototype.get(key) 를 통해 접근한다. - key는 그 요소의 value를 가져올 수 있어야 한다.
- Object는 비슷하게 key를 통해 value를 가져오는데 문법이 다르다.
- Map에 key가 존재하는 지 보기 위해선 > map.has(1);
- Object에서는 좀 더 코딩을 해야하는데
map.get(1) // 2 obj.id // 1 obj['id'] // 1 //1) var isExist = obj.id === undefined; //check if obj has that property defined before. //2) isExist = 'id' in obj; //which will apply for inherited property as well.
※ 알아둘 것 : Object에서는 Object.prototype.hasOwnProperty()를 가지고 있어서 Object 자신의 poperty로서 정의된 key를 가지는지 체크할 수 있다. - 단지, 그 객체에 상속되지 않은 key를 체크할때 좋다. 저자의 의견으로는 여전히 Map이 더 손쉬운 사용으로 요소에 접근할 수 있다고 적어두었다.
[새로운 요소 추가하기]
- Map은 Map.prototype.set()을 제공하여 2개의 인자값을 받는다. : key,value
- 이미 존재하는 key를 사용할 경우, 새로운 value로 기존의 value를 덮어쓰기한다.
- 비슷하게도, Object는 직접적으로 추가한다.
- 둘다 구조 덕분에 요소 추가시에 전체의 데이터를 스캔할 필요는 없다.
map.set(4,5); //{1=>2, 2=>3, 4=>5} map.set(4,6); //{1=>2, 2=>3, 4=>6} obj['gender'] = 'female'; //{id: 1, name: "test", gender: "female"} obj.gender = male; //Both is ok and will overwrite the existing mapped value if property already exists. //{id: 1, name: "test", gender: "male"}
[요소 제거하기]
Object에서는 프로퍼티를 제거하기위한 내장형 메소드가 없다. 대신에, operator delete를 사용할 수 있다.
delete obj.id; //
혹자는 obj.id = undefined; 방식이 더 낫다고 말할 수 있다. (성능 향상측면에서)
하지만, 로직이 꽤나 다르다.
- delete(key)는 객체에서 특정 프로퍼티를 완전히 제거한다.
- "obj[key = undefined" 방식은 그저 프로퍼티의 연결된 value를 "undefined"로 변경할 뿐이다.
따라서, "for...in..." 를 사용할 때, 여전히 프로퍼티의 key를 순회한다.
Map은 괜찮은 삭제를 위해 내장형 메소드를 지원한다.
- delete(key) : 특정 key를 map에서 삭제하고, boolean 값을 반환 (대상 요소가 존재했는지 여부)
- clear() : 모든 요소들을 map에서 삭제한다.
- Object에서 clear()와 같은 기능을 사용하려면 프로퍼티들을 순회하며 제거해야 한다.
[크기 알아내기]
- Map : map.size 을 통해 쉽게 알아낼 수 있다.
- Object : Object.keys(obj).length ( Object.keys() : 특정 객체의 존재하는 key의 배열 ) 를 통해 수동으로 알아내야 한다.
[반복-Iterating]
- 객체의 유형이 iterable 한지 알아보는 법
//typeof <obj>[Symbol.iterator] === “function” console.log(typeof obj[Symbol.iterator]); //undefined console.log(typeof map[Symbol.iterator]); //function
Map은 내장된 반복가능한것 이고 Object는 그렇지 않다.
- 따라서, Map은 "for...of" 반복문으로 반복될 수 있다.
- 혹은 내장 함수 forEach()를 사용한다.
- Object는 Object.keys(obj)로 forEach를 사용한다.
Object.keys(obj).forEach((key)=> console.log(`key: ${key}, value: ${obj[key]}`)); //key: id, value: 1 //key: name, value: test
[언제 Map을 쓰고 언제 Object를 쓰나?]
Map의 모든 이점들이 있음에도 불과하고 Object의 성능이 더 좋다. Object는 Javascript의 가장 기본개념이다.
- Object는 단순한 구조로 저장된 (string 혹은 integer (or Symbol) ) 데이터 사용시 좋은 선택이다. 훨씬 빠르다
- 또한, 개별의 프로퍼티/요소들에 분리된 로직을 적용할때 Object를 사용한다.
var obj = { id: 1, name: "It's Me!", print: function(){ return `Object Id: ${this.id}, with Name: ${this.name}`; } } console.log(obj.print());//Object Id: 1, with Name: It's Me.
( Map으로 똑같이 구현해봐라. 안될거다!)
- JSON은 Object를 직접적으로 지원한다. (Map은 아직이다.)
- delete 작업시에는 Map의 성능이 훨씬 낫다.
- 덧붙여서, Map은 key들의 순서를 보존한다. - Object와는 다르게, 따라서 반복이나 요소의 순서에서 아주 중요하다
- Map은 거대한 데이터를 저장할때 성능이 더 낫다.
[결론]
결론적으로, Map 과 Object 사이에서 어떠한 종류의 데이터를 넣어서 작업할지 그리고 그것을 통해 어떠한 기능을 수행할지에 따라 결정된다. Map은 Object보다 더 많은 이점이 있지만 Object를 절대 대체할 수는 없다.
왜냐하면, Javascript에서 Object는 단순한 hash table 그 이상이다.
[원문]
https://medium.com/front-end-weekly/es6-map-vs-object-what-and-when-b80621932373
'맨땅에코딩 > javascript' 카테고리의 다른 글
apply,call,bind 비교 (0) 2020.09.11 [ES6] WeakSet vs Set [번역] (0) 2020.08.09 [ES6] WeakMap vs Map [번역] (0) 2020.08.09 [ES6] Set vs Array 비교 [번역] (0) 2020.08.07 [ES6] var, let, const 비교 (0) 2020.06.26