es6

94 阅读6分钟

10.1 对象的展开运算符

  • 展开对象
  • 对象的展开,把属性罗列出来,用逗号分隔,放到一个{}中,构成新对象
    const apple = {
        color:'红色',
        shape:'球形',
        taste:'甜'
    }
    console.log({...apple});
  • 合并对象
    const apple = {
        color:'红色',
        shape:'球形',
        taste:'甜'
    }
    const pen = {
        color:'黑色',
        shape:'圆柱形',
        use:'写字'
    }
    // console.log({...apple,...pen});
    console.log({...pen,apple});

10.2 对象展开运算符的注意事项

  • 空对象的展开(如果展开一个空对象,则没有任何效果) console.log({...{},a:1});
  • 非对象的展开(如果展开的不是对象,则会自动将其转为对象,再将其属性罗列出来)
    console.log({...1});
    console.log(new Object(1));
    console.log({...undefined});
    console.log({...null});
    console.log({...true});
  • 如果展开运算符后面是字符串,它会自动转成一个类似数组的对象,因此返回的不是空对象
    console.log({...'alex'});
    console.log([...'alex']);
  • 对象中对象属性的展开(不会展开对象中的对象属性)
    const apple = {
        feature:{
            taste:'甜'
        }
    };
    const pen = {
        feature:{
            color:'黑色',
            shape:'圆柱形'
        },
        use:'写字'
    }

10.3 对象展开运算符的应用

  • 复制对象
    const a = {x:1,y:2};
    const c = {...a};
    console.log(c,c === a);
  • 用户参数和默认参数
    const logUser = userParam => {
        const defaultParam = {
            username:'ZhangSan',
            age:0,
            sex:'male'
        }
        // const {username,age,sex} = {...defaultParam,...userParam};
        // console.log(username,age,sex);

        const param = {...defaultParam,...userParam};
        console.log(param.username);
    }
    logUser()

11.1 Set是什么

  • Set是一系列无序,没有重复值的数据集合
  • Set没有下标去标示每一个值,所以Set是无序的,也不能像数组那样通过下标去访问Set的成员
    const s = new Set();
    s.add(1);
    s.add(2);
    //Set中不能有重复的成员
    s.add(1);
    console.log(s);

11.2 Set实例的方法和属性

    // add
    const s = new Set();
    s.add(2).add(1);
    console.log(s);
    // has (判断)
    console.log(s.has(1));
    console.log(s.has(0));
    // delete:使用delete删除不存在的成员,什么都不会发生,也不会报错
    s.delete(2)
    console.log(s);
    // clear:全部清除
    s.clear()
    console.log(s);
    // forEach:value代表每一个成员,key=value,set本身
    s.forEach(function(value,key,set){
        console.log(value,key,set);
    },console.log(this))
    console.log(s,111);
    // 按照成员添加进集合的顺序遍历
    s.forEach((value,key,set)=>{
        console.log(value,key,set);
    },console.log(this))

    // size等同于length
    console.log(s.size);
    console.log(s);

11.3 Set构造函数的参数

    // 数组
    const s = new Set([1,2,2]);
    console.log(s);
    <p>1</p>  // nodelist
    <p>2</p>
    <p>3</p>
    
    // 字符串、arguments、NodeList、Set等
    console.log(new Set('hih'));
    function func(){
        console.log(new Set(arguments));
    }
    func(1,2,5);
    console.log(new Set(document.querySelectorAll('p')));

    const s = new Set([1,2,1]);
    console.log(new Set(s)===s);
    console.log(s);

11.4 Set的注意事项

  • 什么时候用Set?
    1. 数组和字符串去重时
    2. 不需要通过下标访问,只需要遍历时
    3. 为了使用Set提供的方法和属性时(add delete clear has forEach size)
    // 判断重复的方式
    // Set对重复值的判断基本遵循严格相等(===);
    // 但是对于NaN的判断与===不同,Set中的NaN等于NaN
    const s = new Set([NaN,2,NaN])
    const s = new Set([1,2,1]);
    console.log(s);
    const s = new Set();
    s.add({}).add({})
    console.log({}==={});
    console.log(s);

11.5 Set的应用

    // 数组去重
    const s = new Set([1,2,1]);
    console.log(s);
    console.log([...s]);
    console.log([...new Set([1,2,1,1,1,3])]);
    // 字符串去重
    const s = new Set('abbbacbd');
    //数组转字符串
    // console.log([...s].join(''));
    console.log([...new Set('abbbacbd')].join());
    // 存放DOM元素
    const s = new Set(document.querySelectorAll('p'));
    console.log(s);
    s.forEach(function(elem){
        elem.style.color = 'red'
        elem.style.backgroundColor = 'yellow'
    })

12.1 Map是什么

    // map和对象都是键值对的集合
    const person = {
        // 键->值
        name:'alex',
        age:18
    }
    const m = new Map();
    m.set('name','alex')
    console.log(m);
    // Map和对象的区别
    // 对象一般用字符串当作键
    const obj = {
        name:'alex',
        true:'true'
    }
    
    // 基本数据类型:数字、字符串、布尔值、undefined、null
    // 引用数据类型:对象([]、{}、函数、Set、Map等)
    // 以上都可以作为Map的键
    const m = new Map();
    m.set('name','alex');
    m.set(true,'true');
    m.set({},'object');
    m.set(new Set([1,2]),'set');
    m.set(undefined,'undefined');
    console.log(m);

12.2 Map实例的方法和属性

    const m = new Map();
    // 使用set添加的新成员,键如果已经存在,后添加的键值对覆盖已有的
    m.set(true,'true').set('age',18).set('age',20);
    console.log(m);

    // get
    console.log(m.get(true));
    console.log(m.get('age'));
    // get 获取不存在的成员,返回undefined
    console.log(m.get(false));

    // has
    console.log(m.has('age'));
    console.log(m.has('undefined'));

    // delete
    m.delete('age');
    console.log(m);
    // 使用delete删除不存在的成员,什么都不会发生,也不报错

    // clear
    m.clear();
    console.log(m);

    // forEach
    m.forEach(function(value,key,map){
        console.log(value,key,map,111);
    })

    // map等同于length
    console.log(m.size);
    console.log(m);

12.3 Map构造函数的参数

    // 数组
    // 只能传二维数组,而且必须体现出键和值
    console.log(
        new Map([
            ['name','alex'],
            ['age',18]
        ])
    );
    // Set、Map等
    // Set中也必须体现出键和值
    const s = new Set([
        ['name','alex'],
        ['age',18]
    ])
    console.log(new Map(s));
    console.log(s);  //set
    // 复制了一个新的Map
    const m1 = new Map([
        ['name','alex'],
        ['age',18]
    ])
    console.log(m1);
    const m2 = new Map(m1);
    console.log(m2,m2===m1); // map

12.4 Map的注意事项

    // 判断键名是否相同的方式
    // 基本遵循严格相等(===)
    // 例外就是NaN,Map中NaN也是等于NaN
    const m = new Map();
    console.log(m.set(NaN,1).set(NaN,2))

    // 什么时候使用Map
    // 如果只是需要key->value的结构,或者需要字符串以外的值做键,使用Map更合适

    // 只有模拟现实世界的实体时,才使用对象
    // const person = {}

12.5 Map的应用

    <p>1</p>
    <p>2</p>
    <p>3</p>
    
    // 解构赋值
    const [p1,p2,p3] = document.querySelectorAll('p')
    console.log(p1,p2,p3);
    const m = new Map();
    m.set(p1,'red').set(p2,'green').set(p3,'blue');
    1
    const m = new Map([
        [p1,'red'],
        [p2,'green'],
        [p3,'blue'],
    ])
    console.log(m);
    m.forEach((value,elemt)=>{
        elemt.style.color = value
    })
        <p>1</p>
        <p>2</p>
        <p>3</p>
        
     const m = new Map([
        [p1,{
            color:'red',
            backgroundColor:'yellow',
            fontSize:'40px'
        }],
        [p2,{
            color:'green',
            backgroundColor:'pink',
            fontSize:'40px'
        }],
        [p3,{
            color:'blue',
            backgroundColor:'orange',
            fontSize:'40px'
        }],
    ])
    console.log(m);
    m.forEach((prop,elemt)=>{
        for(const p in prop){
            elemt.style[p]=prop[p]
        }
    })

13.1 iterator

    // lterator的作用
    // lterator:遍历器(迭代器)
    // console.log([1,2][Symbol.iterator]());
    const it = [1,2][Symbol.iterator](); // value是值,done是否遍历完成
    console.log(it.next()); // {value: 1, done: false}
    console.log(it.next()); // {value: 2, done: false}
    console.log(it.next()); // {value: undefined, done: true}
    // it:可遍历对象(可迭代对象)
    // Symbol.iterator:可遍历对象的生成方法
    // Symbol.iterator(可遍历对象的生成方法)-->it(可遍历对象)-->it.next()
    // -->it.next()-->...(知道done为true)

13.2 iterator解惑

    // 为什么需要iterator遍历器
    // iterator遍历器是一个统一的遍历方式

    // 1. 数组天生就有iterator
    console.log([][Symbol.iterator]());

    // 如何更方便的使用iterator
    // Symbol.iterator->it->next()

    // 我们一般不会直接使用iterator去遍历

13.3 for...of的用法1

    // 原理
    const arr = [1,2,3];
    const it = arr[Symbol.iterator]();
    let next = it.next();
    console.log(next);
    while(!next.done){
        console.log(next.value); // 123
        next = it.next();
        console.log(next);
    }
    // 等同于
    for(const item of arr){
        console.log(item);
    }
    // for...of循环只会遍历出那些done为false时,对应的value值

13.4 for...of的用法2

    // value值
    // 与break、continue一起使用
    const arr = [1,2,3];
    for(const item of arr){
        if(item === 2){
            // break;
            continue;
        }
        console.log(item);
    }
    // 在for...of中取得数组的索引
    const arr = [1,2,3];
    // 1. keys()得到的是索引的可遍历对象,可以遍历出索引值
    console.log(arr.keys());
    for(const key of arr.keys()){
        console.log(key);
    }

    // 2. value()得到的是值的可遍历对象,可以遍历出值
    for(const value of arr.values()){
        console.log(value);
    }

    // 3. entries()得到的是索引+值组成的数组的可遍历对象
    for(const entries of arr.entries()){
        console.log(entries); // 索引+值
    }

    // 4. 解构赋值
    for(const [index,value] of arr.entries()){
        console.log(index,value);
    }

13.5 原生可遍历与非原生可遍历

    // 什么是可遍历
    // 只要有Symbol.iterator方法,并且这个方法可以生成可遍历对象,就是可遍历的
    // 只要可遍历,就可以使用for...of循环来统一遍历

    // 2. 原生可遍历的有哪些
    // 数组
    // 字符串
    // Set
    // Map
    // arguments
    // NodeList
    // 3. 非原生可遍历的有哪些
    // 一般的对象
    const person = {sex:'male',age:18}
    // // 给对象添加symbol.iterator方法(原理)
    person[Symbol.iterator] = () => {
        let index = 0;
        return {
            next(){
                index++
                if(index === 1){
                    return {
                        value:person.age,
                        done:false
                    }
                }else if(index === 2){
                    return {
                        value:person.sex,
                        done:false
                    }
                }else {
                    return {
                        done:true
                    }
                }
            }
        }
    }
    for(const item of person){
        console.log(item);
    }
    // 4. 有length和索引属性的对象
    const obj = {
        0:'alex',
        1:'male',
        length:2
    };
    // 1
    obj[Symbol.iterator] = () => {
        let index = 0;
        return {
            next(){
                let value,done;
                if(index<obj.length){
                    value = obj[index];
                    done;false
                }else{
                    value = undefined;
                    done = true;
                }
                index++;
                return{
                    value,done
                }
            }
        }
    }

    //2
    obj[Symbol.iterator] = Array.prototype[Symbol.iterator];
    
    for(const item of obj){
        console.log(item);
    }

13.6 使用iterator的场合

    // 1. 原生可遍历的
    // Array数组
    // String字符串
    // Set
    // Map
    // 函数的arguments
    // NodeList对象
    // 以上都可以展开或遍历
    // 2. 数组的展开运算符
    console.log(...new Set([1,2,3]));
    // 3. 数组的解构赋值
    const [a,b] = [...new Set([3,4])]
    // 4. Set和Map的构造函数
    // new Set(iterator)
    // new Map(iterator)