美文网首页工作生活
ES6学习笔记(四)

ES6学习笔记(四)

作者: 彼得朱 | 来源:发表于2019-07-04 18:55 被阅读0次
    7.png

    十五、Map和WeakMap

    1、Map

    用途:类似json,但是 json 的键(key)只能是字符串

    ​ map 的 key 可以是任意类型

    使用:定义 let map = new Map();

           设置    map.set(key,value);    // 设置一个值
    

    ​ 获取 map.get(key); //获取一个值

    ​ 删除 map.delete(key); //删除一项

    ​ 判断 map.has(key); //判断

    ​ 清空 map.clear(); //清空

    ​ 循环 for(let [key,value] of map){}

    ​ for(let key of map.keys()){}

    ​ for(let value of map.values()){}

    ​ for(let [k,v] of map.entries()){}

    ​ map.forEach((val,key)=>{

    ​ })

    // 定义
    let map = new Map();
    let json = {
        a: 1,
        b: 2
    };
    
    // 设置
    map.set('a', 'aaa');
    map.set(json, 'aaa');
    map.set('aaa', json);
    console.log(map); //输出 Map(3) {"a" => "aaa", {…} => "aaa", "aaa" => {…}}
    
    // 获取
    console.log(map.get('a')); //输出  aaa
    
    // 删除
    map.delete('a');
    console.log(map); //输出Map(2) {{…} => "aaa", "aaa" => {…}}
    
    //判断
    console.log(map.has('a')); //输出 false
    
    //清空
    map.clear();
    console.log(map); // 输出 Map(0) {}
    
    // for循环
    //重新设置
    
    map.set('a', 'aaa');
    map.set(json, 'aaa');
    map.set('aaa', json);
    for (let [key, value] of map) {
        console.log(key, value); //循环输出每一个键值对
    }
    map.forEach((value,key)=>{
        console.log(value,key);
    });
    
    

    注意:map和set方法很多一样,除了map 多了一个get(key)方法。

    2、WeakMap

    注意:key只能是对象,但是用处不大

    // 定义
    let map = new WeakMap();
    let json = {
        a: 1,
        b: 2
    };
    map.set(json,'1');
    console.log(map);  //输出 WeakMap {{…} => "1"}
    
    let errmap = new WeakMap();
    errmap.set('1','1');
    console.log(errmap); // 输出 Uncaught TypeError
    
    

    总结:Set 里面是数组,不重复,没有key,没有get方法

    ​ Map 对json功能增强,key可以是任意类型值

    十六、数字变化和Math新增东西

    1、数字(数值)变化

    (1)进制

    二进制(binary)

    let a = 0b01010;

    八进制 (Octal)

    let b = 0c666;

    十六进制

    ccc

    (2)Number方法

    Number.isNaN() 等同于isNaN(),只是挂载到了Number身上

    Number.isFinite() 判断是不是数字

    Number.isInteger 判断是不是整数

    .....

    安全整数:-(253-1)~(253-1) 包含边界

    Number.isSafeInteger() 判断是不是安全整数

    Number.MAX_SAFE_INTEGER 最大安全整数

    Number.MIN_SAFE_INTEGER 最小安全整数

    2、Math

    Math.abs()

    Math.sqrt()

    Math.sin()

    Math.trunc() 截取,只保留整数部分

    console.log(Math.trunc(4.5));   //输出  4
    console.log(Math.trunc(-4.3));  //输出  -4
    

    Math.sign() 判断一个数到底是正数、负数、0

    console.log(Math.sign(-5));   //输出  -1
    console.log(Math.sign(5));    //输出  1
    console.log(Math.sign(0));    //输出  0
    console.log(Math.sign(-0));   //输出  -0
    console.log(Math.sign('abc'));//输出  NaN
    

    Math.cbrt() 计算立方根

    console.log(Math.cbrt(27));  //输出 3
    
    

    十七、ES2018(ES9)新增东西

    1、命名捕获

    语法:(?<名字>)

    一个例子:(日期拆分)

    //以前的
    let str = '2018-03-20';
    
    let reg = /(\d{4})-(\d{2})-(\d{2})/;
    
    let dataArr = str.match(reg);
    console.log(dataArr);
    let year = dataArr[1];
    let month = dataArr[2];
    let day = dataArr[3];
    console.log(year,month,day); //输出  2018 03 20
    
    
    //ES9
    let str = '2018-03-20';
    
    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    
    let {year,month,day} = str.match(reg).groups;
    console.log(year, month, day);  //输出  2018 03 20
    
    

    反向引用: \1 \2 12

    反向引用命名捕获: 语法:\k<名字>

    let reg = /^(?<Strive>welcome)-\k<Strive>$/;
    
    let str = 'a-a';
    let str2 = 'Strive-Strive';
    let str3 = 'welcome-welcome';
    console.log(reg.test(str));  //  false
    console.log(reg.test(str2)); //  false
    console.log(reg.test(str3)); //  true
    

    替换:replace

    let str = '2018-03-20';
    
    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    
    str = str.replace(reg,'$<day>/$<month>/$<year>');
    console.log(str);  //输出 20/03/2018
    
    let str = '2018-03-20';
    
    let reg = /(?<year>\d{4})-(?<month>\d{2})-(?<day>\d{2})/;
    
    str = str.replace(reg,(...args)=>{
        console.log(args);
        let {year,month,day} = args[args.length-1];
        return `${day}/${month}/${year}'`;
    });
    console.log(str);  //输出 20/03/2018
    

    注意:return的时候用的是{},直接替换用的是<>

    2、dotAll模式

    之前:'.'在正则里面表示匹配任意东西,但是不包括\n

    let reg = /\w+/gims;

    3、标签函数

    function fn(){

    }

    fn() //这样调用就是普通函数

    fnaaa //注意用的是反斜杠

    function fn(args){
        return args[0].toUpperCase();
    }
    console.log(fn`welcome`);  //输出  WELCOME
    

    十八、Proxy的使用

    作用:1、扩展(增强)对象、方法一些功能

    ​ 2、比如Vue中的拦截

    ​ 3、预警、上报、扩展、统计、增强对象等等

    它是设计模式的一种,代理模式

    语法:

    ​ new Proxy(target,handler);

    ​ let obj = new Proxy(被代理的对象,对代理的对象做什么操作)

    ​ handle{

    ​ set(){} //设置的时候干的事情

    ​ get(){} //获取干的事情

    ​ deleteProperty(){} //删除

    ​ has(){} //问你有没有这个东西 'xxx' in obj

    ​ apply() //调用函数处理,拦截方法

    ​ .......

    ​ }

    例1:(增加一个代理对象,访问不是原对象属性时会抛出错误,这些是访问之前的操作)

    let obj = {
        name:'Strive'
    }
    
    let newObj = new Proxy(obj,{
        get(target,property){
            // 访问之前可以做的操作
            console.log(`您访问了${property}属性`);  //您访问了name属性
            if(property in target){
                return target[property];
            }else{
                throw new ReferenceError(`${property}属性不在此对象上`);
            }
        }
    })
    
    console.log(newObj.name);  //Strive
    console.log(newObj.age);   //没加判断之前访问默认是 undefined,加了之后会
    //显示Uncaught ReferenceError: age属性不在此对象上
    
    

    例2:DOM.div() DOM.a(); DOM.ul()

    const DOM = new Proxy({},{
        get(target,property){
            return function(attr={},...children){
                const el = document.createElement(property);
    
                // 添加属性
                for(let key of Object.keys(attr)){
                    el.setAttribute(key,attr[key]);
                }
                // 添加子元素
                for(let child of children){
                    if(typeof child == 'string'){
                        child = document.createTextNode(child);
                    }
                    el.appendChild(child);
                }
    
                return el;
            }
        }
    });
    
    let oDiv = DOM.div(
        {id:'div1',class:'aaa'},'我是div','哈哈哈',
        DOM.a({href:'http://www.baidu.com'},'访问官网'),
        DOM.ul({},
               DOM.li({},'1111'),
               DOM.li({},'2222')
              )
    )
    
    window.onload = function(){
        document.body.appendChild(oDiv);
    }
    

    运行结果:

    2.png

    例3:set(),设置拦截,设置一个年龄,保证是整数,且范围不超过200

    let obj = new Proxy({},{
        set(target,prop,value){
            if(prop == 'age'){
                if(!Number.isInteger(value)){
                    throw new TypeError('年龄必须为整数');
                }
                if(value>200){
                    throw new RangeError('年龄超标了,必须小于200岁');
                }
            }
            target[prop] = value;
        }
    });
    
    obj.a = 123;
    obj.name = 'strive';
    obj.age = 220;
    console.log(obj);    //输出  Uncaught RangeError: 年龄超标了,必须小于200岁
            
    

    例3:deleteProperty()、has()

    let json = {
        a:1,
        b:2
    }   
    
    let newJson = new Proxy(json,{
        deleteProperty(target,property){
            console.log(`您要删除${property}属性`);   //输出 您要删除a属性
            delete target[property];
        },
        has(target,property){
            console.log('判断是否存在调用has方法');   // 输出 判断是否存在调用has方法
            return property in target;
        }
    });
    
    console.log('a' in newJson);// 这里调用 has 方法,输出true
    delete newJson.a;      // 这里调用 delete 方法
    console.log(newJson);  // 输出 Proxy {b: 2}
    

    例4:apply() :拦截

    function fn(){
        return '我是函数';
    }
    let newfn = new Proxy(fn,{
        apply(){
            return '函数吗?';
        }
    });
    console.log(newfn());  //输出 函数吗?
    

    注意:apply()上面的只是拦截到了,并没有执行完函数,需要和reflect配合使用

    十九、Reflect的使用

    反射。(相对于执行函数)

    Reflect.apply(调用的函数,this指向,参数数组);

    与fn.apply() 类似

    Reflect :思想 通过Reflect对象身上直接拿到语言内部东西

    //例1
    function sum(a,b){
        return a+b;
    }
    
    let newSum = new Proxy(sum,{
        apply(target,context,args){
            return Reflect.apply(...arguments);  //反射调用
        }
    });
    
    console.log(newSum(2,3));  //前面加了reflect,这里可以得到 5
    
    //例2
    function show(...args){
        console.log(this);   
        console.log(args);   
    }
    
    show(1,2,3,4);        // 只有参数,this指向:window  args:[1, 2, 3, 4]
    show.call('abc',1,2,3,4);// this指向:String {"abc"} args:[1, 2, 3, 4]
    show.apply('abcd',[2,3,3,2]);//this指向:String {"abcd"}  args:[2, 3, 3, 2]
    Reflect.apply(show,'aaaa',[1,2,3,4]);//this指向:String {"aaaa"}  args:[1, 2, 3, 4]
    
    //例3
    console.log(Reflect.has(Object,'assign')); //输出true
    
    //例3
    let json = {a:1,b:2};
    // delete json.a;
    Reflect.deleteProperty(json,'a');  //等同于上面这句
    console.log(json); //输出  {b: 2}
    

    相关文章

      网友评论

        本文标题:ES6学习笔记(四)

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