Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

2.ES6详解-Map Set Symbol #14

Open
Geek-James opened this issue Jul 18, 2019 · 1 comment
Open

2.ES6详解-Map Set Symbol #14

Geek-James opened this issue Jul 18, 2019 · 1 comment
Labels

Comments

@Geek-James
Copy link
Owner

特性

ES6提供了”值-值“对的数据结构,键名不仅可以是字符串,也可以是对象。它是一个更完善的Hash结构。

1.键值对,键可以是对象

    const map1 = new Map();
    const objkey = {p1:'v1'};
    map1.set(objkey,'hello');
    console.log(map1.get(objkey)); // hello
    

2.Map可以接受数组作为参数,数组成员还是一个数组,其中有两个元素,一个表示键一个表示值。

    const map2 = new Map([['name','james'],['age',18],['profession','software']]);
    console.log(map2.get('name')); // james
    console.log(map2.get('age'));// 18
    

操作

1.size 获取map的大小长度

    const map2 = new Map([['name','james'],['age',18],['profession','software']]);
    console.log(map2.size); // 3

2.设置键值对,键可以是各种类型,包括undefined,function等

  const map4 = new Map();
    map4.set('k1',5);
    map4.set(222,'哈哈哈');
    map4.set(undefined,'ggggg');
    const fun = function(){
        console.log('hello 我是方法');
    }
    map4.set(fun,'fun');
    console.log('map4 size :%s',map4.size);  // 4
    console.log('undefined value :%s',map4.get(undefined)); //ggggg
    console.log('fun value:%s',map4.get(fun)); //fun

3.也可对set进行链式调用。

map4.set('k2', 2).set('k3', 4).set('k4', 5)

4.get 获取键对应的值

    const map4 = new Map();
    map4.set('k1',5);
    
  1. has 判断键是否存在
    const map5 = new Map();
    map5.set(undefined,4);
    console.log('map undefined:%s',map5.has(undefined)); //true
    console.log('map k1:%s',map5.has('k1'));// false

6.delete 删除键值对

    const map5 = new Map();
    map5.set(undefined,4);
    console.log('map undefined:%s',map5.has(undefined)); //true
    map5.delete(undefined);
    console.log('map undefined:%s',map5.has(undefined)); //false

7.clear 删除map中所有的键值对

    const map5 = new Map();
    map5.set('a','ad').set('b',111).set(3,333).set(fun,'demo');
    console.log(map5.size); // 4
    map5.clear();
    console.log(map5.size); // 0
  • 注意点:

如果 Map 的键是一个简单类型的值(数字、字符串、布尔值),则只要两个值严格相等,Map 将其视为一个键,比如0和-0就是一个键,布尔值true和字符串true则是两个不同的键。另外,undefined和null也是两个不同的键。虽然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

遍历

1.keys() 遍历map的所有key

    for (let key of map5.keys()) {
        console.log(key);
    }

2.values() 遍历map的所有value

 for (let key of map5.values()) {
        console.log(key);
    }

3.entries() 遍历map的所有键值对

方法一:

 for (let item of map5.entries()) {
        console.log("key:%s, value:%s",item[0],item[1]);
    }

方法二:

    for(let [key,value] of map5.entries()) {
        console.log("key:%s, value:%s",key,value);
    }

4.forEach 遍历map所有的键值对

    map5.forEach(function(value,key,map){
        console.log("key:%s, value:%s, map:%s",key,value,map.size);
    }); 

forEach知识拓展:
forEach有第二个参数,可以用来绑定this。
这样有个好处,map的存储的数据和业务处理对象可以分离,业务处理对象可以尽可能的按职责分割的明确符合SRP原则。

   const output = {
        log:function(key,value){
            console.log("key:%s,Value:%s",key,value);
        },
        say:function(){
            console.log("来打我呀");
        }
    };

    map5.forEach(function(key,value){
        this.log(key,value);
        this.say();
    },output);

和其他结构的互转

1.Map To Array
使用扩展运算符(...) 可将map内的元素都展开为数组

    console.log(...map5);
    
    (2) ["a", "ad"]0: "a"1: "ad"length: 2__proto__: Array(0) (2) ["b", 111] (2) [3, 333] (2) [ƒ, "demo"]
    
    let arr = [...map5];
    console.log(arr);
    [...map5.keys()];
    [...map5.values()];
    [...map5.entries()];
    
   (4) [Array(2), Array(2), Array(2), Array(2)]
    0: (2) ["a", "ad"]
    1: (2) ["b", 111]
    2: (2) [3, 333]
    3: (2) [ƒ, "demo"]
    length: 4
    __proto__: Array(0)

结合数组的map方法、filter方法,可以实现 Map 的遍历和过滤(Map 本身没有map和filter方法)。

const map0 = new Map()
.set(1,'a')
.set(2,'b')
.set(3,'c');

const map1 = new Map(
    [...map0].filter(([k,v])=>k<3)
);
// 产生map结构{1=>'a',2=>'b'};
const map2 = new Map(
    [...map0].map(([k,v])=>[k*2,'_'+v])
);
// 产生map结构{2 => "_a", 4 => "_b", 6 => "_c"}

2.Array To Map
使用数组来构造一个map

    const map6 = new Map([
        ['name','james'],
        ['age',26]
    ])

    console.log(map6);
    
    Map(2) {"name" => "james", "age" => 26}
    

3.Map To Object

写一个转换函数,遍历map的所有元素,将元素的键和值作为对象属性名和值写入Object中。

function mapToObject(map) {
        // 创建一个空对象
        let obj = {};
        for (let [k,v] of map) {
            obj[k] = v; 
        }
        return obj;
    }
    console.log(mapToObject(map6));
    
   // {name: "james", age: 26}

4.Object To Map

同理,再写一个转换函数遍历Object,将属性名和值作为键值对写入Map。

function objectToMap(obj) {
        let map = new Map();
        for (let [k,v] of Object.entries(obj)){
            map.set(k,v);
        }
        return map;
    }
    let objs = mapToObject(map6);
    console.log(objectToMap(objs));
    // Map(2) {"name" => "james", "age" => 26}

注意点:

object 不能实现 for of 迭代循环,会报'x' is not iterable的TypeError.

这个值作为 for…of 的表达式右值,或者作为一个函数的参数,如 Promise.all 或者 TypedArray.from, 不是一个 可迭代对象. 一个可迭代对象可以是一个内置可迭代类型,如Array, String 或 Map, 一个 generator 生成结果, 或者一个实现了可迭代协议的对象.

方案一:

做为替代你必须使用 Object.keys

 function objectToMap(obj) {
        let map = new Map();
        for (let k of Object.keys(obj)){
            map.set(k,obj[k]);
        }
        return map;
    }

或 Object.entries 来迭代对象的属性或属性值.

function objectToMap(obj) {
        let map = new Map();
        for (let [k,v] of Object.entries(obj)){
            map.set(k,v);
        }
        return map;
    }

5.set To map

将创建好的set在创建map的构造函数时,直接传入

    const set = new Set([
        ['foo',1],
        ['bar',2]
    ]);
    const map9 = new Map(set);
    console.log(map9);
    // Map(2) {"foo" => 1, "bar" => 2}

6.map To set

遍历map中的键值,然后add到set中

    function mapToSet(map) {
        let set = new Set();
        for (let [k,v] of map) {
            set.add([k,v]);
        }
        return set;
    }
    // Set(2) {Array(2), Array(2)}

7.Map 转为 JSON
Map 转为 JSON 要区分两种情况。一种情况是,Map 的键名都是字符串,这时可以选择转为对象 JSON。

@Geek-James Geek-James changed the title 2.Map Set Symbol 2.ES6详解-Map Set Symbol Jul 18, 2019
@Geek-James Geek-James added the ES6 label Jul 19, 2019
@cloudcome
Copy link

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Projects
None yet
Development

No branches or pull requests

2 participants