美文网首页前端开发那些事儿
ES6新特性Symbol,Set,Map

ES6新特性Symbol,Set,Map

作者: 大吉的罐头 | 来源:发表于2021-03-06 13:18 被阅读0次

    新数据类型 Symbol

    声明方式
    • Symbol 不是对象,可以理解成不能重复的独立字符串,括号内对象会转化为字符串
    • Symbol for 在全局中定义查找,创建多个其实查找是同一个
    • Symbol.keyFor 返回已经登记的Symbol类型的key
    const obj={
        name:'daji',
        toString(){
            return this.name
        }
    }
    let n=Symbol(obj)
    console.log(n); //Symbol(daji)
    
    let c=Symbol([1,2,3])
    console.log(c);  //Symbol(1,2,3)
    
    let s1=Symbol('foo')
    let s2=Symbol('foo')
    console.log(s1===s2); //false
    
    let a1=Symbol.for('foo')
    let a2=Symbol.for('foo')
    console.log(a1===a2);  //true
    
    const x1=Symbol('foo')
    console.log(Symbol.keyFor(x1)); //undefined
    const x2=Symbol.for('foo')
    console.log(Symbol.keyFor(x2)); //foo
    
    应用场景
    • 对象内如果有重复key值会覆盖的解决方式
    const stu1=Symbol('李四')
    const stu2=Symbol('李四')
    const grade={
        [stu1]:{address:'yyy',tel:'111'},
        [stu2]:{address:'yyy',tel:'111'}
    }
    console.log(grade); //{Symbol('李四'):{...},Symbol('李四'):{...}} 不会覆盖,显示两个
    console.log(grade[stu1]);
    console.log(grade[stu2]);
    
    • 一定程度上保护构造函数的属性
    let sym=Symbol('hello')
    class User{
        constructor(name){
            this.name=name
            this[sym]='hello.com'
        }
        getName(){
            return this.name+this[sym]
        }
    }
    let user=new User('daji')
    console.log(user.getName()); //dajihello.com
    
    for(let key in user){
        console.log(key);  //name 无法读到Symbol('hello')属性
    }
    for(let key of Object.keys(user)){
        console.log(key);  //name 无法读到Symbol('hello')属性
    }
    for(let key of Object.getOwnPropertyNames(user)){
        console.log(key);  //name 无法读到Symbol('hello')属性
    }
    for(let key of Object.getOwnPropertySymbols(user)){
        console.log(key);  //Symbol(hello)   只能读到symbol属性,读不到name
    }
    for(let key of Reflect.ownKeys(user)){
        console.log(key);   //name Symbol(hello)  都能读到
    }
    
    • 消除魔术字符串(重复出现的字符串)
    const shpeType={
        triangle:Symbol(),  //triangle:'triangle' vlaue值不重要用symbol替代
        circle:Symbol()     //circle:'circle' 
    }
    function getArea(shape){
        let area = 0
        switch(shape){
            case shpeType.triangle:  //避免case 'triangle' 重复出现此字符串
                area=1
                break
            case shpeType.circle:
                area=2
                break
        }
        return area
    }
    console.log(getArea(shpeType.triangle));  //返回1  避免getArea('triangle') 重复出现此字符串
    

    新数据结构 Set

    常用方法
    //唯一的 重复的2只会保留1个2
    let s=new Set([1,2,3,2])
    s.add('es').add('hi')  //链式添加
    s.delete(2)  //删除
    s.clear()   //清空
    console.log(s.has('hi')); //是否包含
    console.log(s); 
    console.log(s.size);  //size相当于length
    
    遍历方法
    let s1=new Set([1,2,3,2])  //只保留了1个2
    console.log(s1);
    s1.forEach(item=>{
        console.log(item);  // 1 2 3
    })
    for(let item of s1){
        console.log(item);   //1 2 3
    }
    for(let item of s1.keys()){
        console.log(item);   //1 2 3
    }
    for(let item of s1.values()){
        console.log(item);   //1 2 3
    }
    for(let item of s1.entries()){
        console.log(item);   //[1,1] [2,2] [3,3] key和value
    }
    
    应用场景
    • 数组去重
    let arr = [1,2,3,4,2,3]
    let s= new Set(arr)
    console.log(s);  //set(4){1,2,3,4}
    
    • 合并去重
    let arr1=[1,2,3,4]
    let arr2=[2,3,4,5,6]
    let s1=new Set([...arr1,...arr2])  //扩展运算符打散 set(6){1,2,3,4,5,6}
    console.log(s1);      //set(4) [1,2,3,4,5,6]
    console.log([...s1]); //变成数组形式 [1,2,3,4,5,6]
    console.log(Array.from(s1));  //变成数组形式 [1,2,3,4,5,6]
    
    • 交集
    let s3=new Set(arr1);
    let s4=new Set(arr2);
    let result=new Set(arr1.filter(item=>s4.has(item)));
    console.log(result); //set(4) {2,3,4}
    
    • 差集 (两数组合并后除去交集)
    let result1=new Set(arr1.filter(item=>!s4.has(item)));
    let result2=new Set(arr2.filter(item=>!s3.has(item)));
    console.log(result1); //set{1}
    console.log(result2); //set{5,6}
    console.log([...result1,...result2]); //[1,5,6]
    
    • WeakSet (只能存储对象)
    let ws =new WeakSet()
    const obj1={a:1}
    const obj2={b:2}
    ws.add(obj1)
    ws.add(obj2)
    ws.delete(obj1)
    console.log(ws);
    console.log(ws.has(obj2));
    //WeakSet 不能遍历
    ws.forEach(item=>{console.log(item);})
    //WeakSet 是弱引用,不进入垃圾回收机制(值被引用一次+1)不存在回收问题,适合临时存放一些对象
    

    新数据结构 Map

    常用方法
    //Map键值对的方式,但key可以为对象
    let m=new Map()
    let obj={
        name:'daji'
    }
    m.set(obj,'es')  //设置  对象做为key,value值对应es
    console.log(m); 
    console.log(m.get(obj)); //获取 es
    m.delete(obj)
    console.log(m); //删除  空
    console.log(m.has(obj)); //false
    
    //这样设置key和value也行
    let map=new Map([
        ['name','daji'],
        ['age',5]
    ])
    console.log(map);
    console.log(map.size);
    console.log(map.has('name')); //true
    console.log(map.has('age')); //true
    map.set('name','zhangsan')
    console.log(map);  //name的value被覆盖为zhangsan
    
    遍历方法
    let map=new Map([
        ['name','daji'],
        ['age',5]
    ])
    //第一个参数是value,第二个参数是key
    map.forEach((value,key) => {
        console.log(value,key);
    });
    //第一个参数是key,第二个参数是value
    for(let [key,value] of map){
        console.log(key,value);
    }
    for(let key of map.keys()){
        console.log(key);
    }
    for(let value of map.values()){
        console.log(value);
    }
    for(let [key,value] of map.entries()){
        console.log(key,value);
    }
    
    应用场景
    • Object对象的应用场景都能使用Map,且Map对键值对的增删改查性能更好
    • WeakMap(键名只支持引用数据类型,例如对象数组function)
    let wm=new WeakMap()
    wm.set([1],2)
    wm.set({
        name:'daji'
    },'es')
    console.log(wm);
    // wm.clear() //报错不支持clear方法
    // wm.size() //报错不支持size方法 wm也不支持遍历 
    
    //弱引用 引用次数不会增加 若当前h1dom元素被删除,垃圾机制也不会回收,会自动消失,有助于防止内存泄漏
    let wm1=new WeakMap()
    let elem=document.getElementsByTagName('h1')
    wm1.set(elem,'info')
    console.log(wm1.get(elem));
    

    相关文章

      网友评论

        本文标题:ES6新特性Symbol,Set,Map

        本文链接:https://www.haomeiwen.com/subject/mpejqltx.html