The difference between Object and Map

Object is the most commonly used reference type data, which can be used to store a collection of key-value pairs, which was added in the first version of ECMAScript

Map is a collection of exclusive key-value pairs, stored in a Hash structure, added in ECMAScript 2015 (Es6)

Common ground: dynamic collection of key-value pairs, support for adding and deleting key-value pairs

difference:

  1. key type
    /**
     * 1. 键的类型
     * Object 
     *  - 键值必须是String或者Symbol,否则会进行数据类型的转换 
     * Map
     *  - 键可以是任意类型,包括对象、数组、函数等,不会进行类型转换,在添加键值对时,会通过严格相等(===)来判断属性是否已经存在
     */
    const obj = {a: 1}
    const arr = [1, 2]
    obj[arr] = 'arr' 
    console.log(obj)  // {a: 1, 1,2: 'arr'}
    
    const map = new Map()
    map.set('a', 1)
    map.set(2, 2)
    map.set(arr, 'arr')
    console.log(map)  //{'a' => 1, 2 => 2, Array(2) => 'arr'}
    // 特例
    // NaN === NaN  ==> false
    const map2 = new Map()
    map2.set(NaN, 1)
    map2.set(NaN, 2)
    console.log(map2)  // {NaN => 2}
  2. order of keys

    /**
     * 2. 键的顺序
     * Object
     * - key是无序的,不会按照添加的顺序返回
     *   - 1.对于大于0的整数,会按照大小进行排序;对于小数和负数会当字符串处理
     *   - 2.对于String类型,按照定义的书序输出
     *   - 3.对于Symbol类型,会直接过滤掉,不进行输出
     *     - 如果想输出Symbol类型,通过Object.getOwnPropertySymbols()方法
     * 
     * Map
     * - key是有序的,按照插入的顺序进行返回
     */
    
     const obj2 = {
       2: 2,
       '1': 1,
       'b': 'b',
       1.1: 1.1,
       0: 0,
       'a': 'a',
       [Symbol('s1')]: 's1',
       [Symbol('s2')]: 's2'
     }
    
     console.log(obj2) // {0: 0, 1: 1, 2: 2, b: 'b', 1.1: 1.1, a: 'a', Symbol(s1): 's1', Symbol(s2): 's2'}
     console.log(Object.keys(obj2)) // ['0', '1', '2', 'b', '1.1', 'a']
    
     const map3 = new Map()
     map3.set(2, 1)
     map3.set('1', 1)
     map3.set('b', 'b')
     map3.set(0, 0)
     map3.set('a', 'a')
     map3.set(Symbol('s1'), 's1')
     console.log(map3.keys()) // {2, '1', 'b', 0, 'a', Symbol(s1)}
  3. key value pair size

     /**
      * 3. 键值对size
      * Object
      *  - 只能手动计算,通过Object.keys()方法,或者通过for...in 循环统计
      * 
      * Map
      *  - 直接通过size属性访问
      * 
       */
    
       const obj3 = {
         'q': 1,
         'w': 2,
         'e': 3
       }
       console.log(Object.keys(obj3).length) // 3
    
       const map4 = new Map()
       map4.set('q', 1)
       map4.set('w', 2)
       map4.set('e', 3)
       console.log(map4.size) // 3
  4. Access to key-value pairs

       /**
        * 4. 键值对的访问
        * Object
        *  - 判断属性是否存在(undefined)
        * 
        * Map
        *  - 判断属性是否存在(has)
        */
    
        const obj4 = {
          name: 'Bulala',
          age: 18
        }
        console.log(obj4.name === undefined) // false
    
        const map5 = new Map()
        console.log(map5.has('name')) // false
  5. iterator(for...of)

        /**
         * 5. 迭代器(for... of)
         * Object
         *  - Object本身是不具备Iterator特性的,不能使用for.. if进行遍历
         * 
         * Map
         *  - Map结构的keys(), values(), entries()方法返回值都具有Iterator特性, 可以使用for.. if进行遍历
         */
        const obj5 = {
          name: 'Bulala',
          age: 18
        }
        // for(let key of obj5) {
        //   console.log(key) // 报错:Uncaught TypeError: obj5 is not iterable
        // }
    
        const map6 = new Map([
          ['name', 'Bulala'],
          ['age', 18]
        ])
        for(let key of map6.entries()) {
          console.log(key) // ['name', 'Bulala'] ['age', 18]
        }
  6. JSON serialization

        /**
         * 6. JSON序列化
         * Object
         *  - Object类型可以通过JSON.stringify()进行序列化操作
         * 
         * Map
         *  - Map结构不能直接进行序列化
         */
    
        const obj6 = {
          name: 'Bulala',
          age: 18
        }
        console.log(JSON.stringify(obj6)) // {"name":"Bulala","age":18}
        const map7 = new Map([
          ['name', 'Bulala'],
          ['age', 18]
        ])
        console.log(JSON.stringify(map7)) // {} 
        // 不能直接序列化,得先转成数值,在进行序列化
        console.log(JSON.stringify(Array.from(map7))) // [["name","Bulala"],["age",18]]

    Summarize:

    type Applicable scene
    Object

    1. Only for data storage, and the attribute value is only a string or Symbol

    2. When it needs to be serialized and converted to JSON

    3. When an instance of an object needs to retain its own properties and methods

    Map

    1. When frequently updating and deleting key-value pairs

    2. When storing a large amount of data, especially when the key type is unknown

    3. Frequent iterative processing is required

    If there are any deficiencies, please advise, and other content will continue to be added in the future.

Guess you like

Origin blog.csdn.net/Star_ZXT/article/details/125020164