ABOUT ME

-

Today
-
Yesterday
-
Total
-
  • [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이 더 손쉬운 사용으로 요소에 접근할 수 있다고 적어두었다.

     

    [새로운 요소 추가하기]

    • MapMap.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
Designed by Tistory.