ES6 中Map数据结构

  • A+
所属分类:ES 6 JavaScript Web

ES6 提供了 Map 数据结构。是键值对的集合,Map类似于对象,但是其键的范围不限于对象的字符串,各种类型的值(包括对象)都可以当作键。

一.Map数据结构

1.基本定义

  • ① Map数据结构的定义
    //例一 创建一个的Map空集合,使用常规的set,get,has,delete方法操作
    const m = new Map();
    const o = {p: 'Hello World'};
    
    m.set(o, 'content')
    m.get(o) // "content"
    
    m.has(o) // true
    m.delete(o) // true
    m.has(o) // false
    
    //例二 使用嵌套数组初始化map对象
    const map = new Map([
      ['name', 'Joey'],
      ['title', 'Author']
    ]);
    
    map.size // 2
    map.has('name') // true
    map.get('name') // "张三"
    map.has('title') // true
    map.get('title') // "Author"
    
    // 例三 任何具有 Iterator 接口、且每个成员都是一个双元素的数组的数据结构,都可以当作Map构造函数的参数。这就是说,Set和Map都可以用来生成新的 Map。
    const set = new Set([
      ['foo', 1],
      ['bar', 2]
    ]);
    const m1 = new Map(set);
    m1.get('foo') // 1
    
    const m2 = new Map([['baz', 3]]);
    const m3 = new Map(m2);
    m3.get('baz') // 3
    

2.Map数据结构的特性

  • ① Map数据结构也是键值对的集合,与对象结构类似,但是对象结构只能使用字符串或者Symbol当做键,而Map的键可以是随意的值或者结构。
    es5中对象作为key值,自动转换为字符串存储
    const data = {};
    const element = document.getElementById('myDiv');
    
    data[element] = 'metadata';
    data['[object HTMLDivElement]'] // "metadata"
    
  • ② Map数据结构key的唯一性,多次赋值,后面的值将覆盖前面的值。
    const map = new Map();
    
    map
    .set(1, 'aaa')
    .set(1, 'bbb');
    
    map.get(1) // "bbb"
    
  • ③ 若读取的是一个未知的键,则返回undefined
    new Map().get('asfddfsasadf')
    // undefined
    
  • ④ 若map结构中key引用的不是同一地址的对象,则视为2个键。
    //一
    const map = new Map();
    
    map.set(['a'], 555);
    map.get(['a']) // undefined
    
    //二
    const map = new Map();
    
    const k1 = ['a'];
    const k2 = ['a'];
    
    map
    .set(k1, 111)
    .set(k2, 222);
    
    map.get(k1) // 111
    map.get(k2) // 222
    
  • ⑤ 针对于基础类型0,-0,+0为同一值;undefinednull不为同一值;虽然NaN不严格相等于自身,但 Map 将其视为同一个键。
    let map = new Map();
    
    map.set(-0, 123);
    map.get(+0) // 123
    
    map.set(true, 1);
    map.set('true', 2);
    map.get(true) // 1
    
    map.set(undefined, 3);
    map.set(null, 4);
    map.get(undefined) // 3
    
    map.set(NaN, 123);
    map.get(NaN) // 123
    

3.Map结构的常规方法

  1. Map
    size 属性:返回 Map 结构的成员总数。
    Map.prototype.set(key, value):set方法设置键名key对应的键值为value,然后返回整个 Map 结构。因此可以采用链式写法。
    Map.prototype.get(key):get方法读取key对应的键值,如果找不到key,返回undefined。
    Map.prototype.has(key):has方法返回一个布尔值,表示某个键是否在当前 Map 对象之中。
    Map.prototype.delete(key):delete方法删除某个键,返回true。如果删除失败,返回false。
    Map.prototype.clear():clear方法清除所有成员,没有返回值。
  2. 范例
    //1.size
    const map = new Map();
    map.set('foo', true);
    map.set('bar', false);
    
    map.size // 2
    
    //2.set
    let map = new Map()
      .set(1, 'a')
      .set(2, 'b')
      .set(3, 'c');
    
    //3.get
    const m = new Map();
    
    const hello = function() {console.log('hello');};
    m.set(hello, 'Hello ES6!') // 键是函数
    
    m.get(hello)  // Hello ES6!
    
    //4.has
    const m = new Map();
    
    m.set('edition', 6);
    m.set(262, 'standard');
    m.set(undefined, 'nah');
    
    m.has('edition')     // true
    m.has('years')       // false
    m.has(262)           // true
    m.has(undefined)     // true
    
    //5.delete
    const m = new Map();
    m.set(undefined, 'nah');
    m.has(undefined)     // true
    
    m.delete(undefined)
    m.has(undefined)       // false
    
    //6.clear
    let map = new Map();
    map.set('foo', true);
    map.set('bar', false);
    
    map.size // 2
    map.clear()
    map.size // 0
    

4.Map数据结构的遍历

  1. Map 结构的实例有四个遍历方法
    Map.prototype.keys():返回键名的遍历器
    Map.prototype.values():返回键值的遍历器
    Map.prototype.entries():返回键值对的遍历器
    Map.prototype.forEach():使用回调函数遍历每个成员
  2. keys(),values(),entries()遍历范例
    //一 keys
    const map = new Map([
      ['F', 'no'],
      ['T',  'yes'],
    ]);
    
    for (let key of map.keys()) {
      console.log(key);
    }
    // "F"
    // "T"
    
    //二 values
    for (let value of map.values()) {
      console.log(value);
    }
    // "no"
    // "yes"
    
    //三 entries
    for (let item of map.entries()) {
      console.log(item[0], item[1]);
    }
    // "F" "no"
    // "T" "yes"
    
    // 或者
    for (let [key, value] of map.entries()) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    
    // 等同于使用map.entries()  因为 Map 结构的默认遍历器接口(Symbol.iterator属性),就是entries方法。
    for (let [key, value] of map) {
      console.log(key, value);
    }
    // "F" "no"
    // "T" "yes"
    map[Symbol.iterator] === map.entries
    // true
    
  3. forEach使用回调函数的方式进行遍历,参数依次是value值,key值,map对象
    map.forEach(function(value, key, map) {
      console.log("Key: %s, Value: %s", key, value);
    });
    
  4. forEach方法还可以接受第二个参数,用来绑定this。
    //下面代码中,forEach方法的回调函数的this,就指向reporter。
    const reporter = {
      report: function(key, value) {
        console.log("Key: %s, Value: %s", key, value);
      }
    };
    
    map.forEach(function(value, key, map) {
      this.report(key, value);
     //this为{report: ƒ}
    }, reporter);
    
zhangfeng

发表评论

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen: