ES6课程学习笔记-day02

复习
    ES6
        
1、特点
    1. ES5升级版本
    2. 提供了简便的语法
        Set、Map
        迭代器
        箭头函数
        ...
    3. 在浏览器上的兼容性比较差

        学习环境  nodejs  ES6
            脚手架
        开发环境  windows ES5
    
2、模块化
    ip/dist/index.html

3、基础语法
    1) let命令
        特点:
            1. 变量无法重复声明
                let a = 1;
                let a = 2; // 报错
            2. 存在块级作用域
                {
                    let a = 1;
                    console.log(a); // 1
                }
                console.log(a); // 报错
            3. 不允许变量的提升
                console.log(a); // 报错
                let a = 1;
            4. 存在暂时性死区
                var temp = 1;
                if(true){
                    temp = 2;
                    let temp; // 报错
                }
            
    2) const命令
        特点:
            1. 存在块级作用域
            2. 存在暂时性死区
            3. 变量无法重复声明
            4. 变量的声明和初始化必须同时进行
                const a;
                a = 1;
                console.log(a); // 报错

    3) 解构(模式匹配)
        1. 数组的解构
            变量的取值为对应索引位置上的值

            var a = 1;
            var b = 2;
            var c = 3;
            console.log(a,b,c); // 1 2 3

            ->ES6
            
            let [a,b,c] = [1,2,3];
            console.log(a,b,c); // 1 2 3


            等号左边个数大于右边
                let [a,b,c] = [1,2];
                console.log(a,b,c); // 1 2 undefined
            等号左边个数小于右边
                let [a,b] = [1,2,3];
                console.log(a,b); // 1 2 
            
        2. 数组解构默认值
            let [a,b,c='d'] = [1,2];
            console.log(a,b,c); // 1 2 d

            默认值生效的前提是,匹配不成功或者是匹配到的值为undefined

        3. 对象的解构
            变量的取值由它对应同名的属性名的值决定
            var obj = {
                name:'xpf',
                age:25,
                gender:'male'
            }
            let {name,age,gender} = obj;
            ==>等价于(对象的简写)
            let {name:name,age:age,gender:gender} = obj;
            
            解构失败时,值为undefined
        
        4. 对象解构的默认值
            var obj = {
                name:'xpf',
                age:25
            }
            let {name,age,gender} = obj;
            console.log(gender); // undefined

            ->

            var obj = {
                name:'xpf',
                age:25
            }
            let {name,age,gender='male'} = obj;
            console.log(gender); // male

            默认值生效的前提是,匹配不成功或者是匹配到的值为undefined

        5. 解构的用途
            1、两个变量的值互换
            2、让函数返回多个值
                将多个返回值放在{}或[]中返回

                es6时通过解构取值比较简单
            3、快速从对象中取值
            4、函数参数默认值
                function sayName({name,age,gender='male'}){

                }
                sayName({name,age})

学习

4、对象的扩展
    ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法
    1) 对象属性的简写
        在之前写对象
            let name = 'xpf';
            let obj = {
                name:name
            }
            console.log(obj.name); // xpf

        ES6的简写
            let name = 'xpf';
            let obj = {
                name
            }
            console.log(obj.name); // xpf

            错误写法:
            let gender = 'xpf';
            let obj = {
                name
            }
            console.log(obj.name); // name is not defined

        对象的解构
            var obj = {
                name:'xpf',
                age:25,
                gender:'male'
            }
            let {name,age,gender} = obj;

            ===> 等价于
            let {name:name,age:age,gender:gender} = obj;

    2) 对象方法的简写
        在之前写对象的方法
            let obj = {
                id:1,
                name:'xpf',
                address:'安徽省',
                sayAddress:function(){
                    console.log('my address is',this.address);
                }
            }
            let {sayAddress} = obj;
            obj.sayAddress(); // my address is 安徽省
            console.log(sayAddress);
        
        ES6的简写
            let obj = {
                id:1,
                name:'xpf',
                address:'安徽省',
                sayAddress(){
                    console.log('my address is',this.address);
                }
            }
            let {sayAddress} = obj;
            obj.sayAddress(); // my address is 安徽省
            console.log(sayAddress);

        注意:
            对象中简写的方法不能够当作构造函数,否则会报错
            let obj = {
                id:1,
                name:'xpf',
                address:'安徽省',
                sayAddress(){
                    console.log('my address is',this.address);
                }
            }
            let {sayAddress} = obj;
            new sayAddress(); // sayAddress is not a constructor

    3) 构造函数的扩展 Object.xxx
        var obj = new Object();
        obj     实例
        Object  构造函数
        Object.prototype   构造函数的原型

        实例能够调用构造函数原型中的方法,但是无法调用构造函数中的方法

        1. Object.is(value1,value2)
            判断两个值是否相等
            var res1 = Object.is(1,1);
            var res2 = Object.is(1,'1');
            var res3 = Object.is('1','1');
            var res4 = Object.is({},{});
            var res5 = Object.is(+0,-0);
            var res6 = Object.is(NaN,NaN);

            console.log(res1); // true
            console.log(res2); // false
            console.log(res3); // true
            console.log(res4); // false
            console.log(res5); // false
            console.log(res6); // true

            与 === 类似,会进行数据类型的比较,但是也有不同
                1、NaN使用Object.is判断的时候,等于自身
                2、+0和-0使用Object.is判断时,不相等
        
        2. Object.assign(target,source1,source2...)
            将所有可枚举属性的值从一个或多个源对象复制到目标对象中,并且返回目标对象
                可枚举:一般指用户自己写的属性,不包含继承的属性
                源对象:source1,source2...
                目标对象:target

            1、合并对象
                let obj1 = {
                    id:1
                }
                let obj2 = {
                    name:'xpf'
                }
                let obj3 = {
                    gender:'male'
                }

                let obj = Object.assign(obj1,obj2,obj3);

                console.log('obj',obj); // { id: 1, name: 'xpf', gender: 'male' }
                console.log('obj1',obj1); // { id: 1, name: 'xpf', gender: 'male' }

                此时,obj1是目标对象,obj2和obj3是源对象
                合并后目标对象自身也会改变

                注意:当合并的对象具有相同的属性名时,属性会被源对象当中具有相同属性名的值覆盖掉
                    let obj1 = {
                        id:1
                    }
                    let obj2 = {
                        name:'xpf'
                    }
                    let obj3 = {
                        name:'male'
                    }
                    let obj = Object.assign(obj1,obj2,obj3);
                    console.log('obj',obj); // { name: 'male', id: 1 }

            2、复制对象(克隆)
                let obj1 = {
                    name:'tom',
                    age:13,
                    gender:'male'
                }

                let obj = Object.assign({},obj1);

                console.log(obj); // { name: 'tom', age: 13, gender: 'male' }
                console.log(obj1); // { name: 'tom', age: 13, gender: 'male' }
                console.log(obj == obj1); // false

                案例:
                一、当源对象中某一个属性值为对象时(即对象嵌套对象)
                    let obj1 = {
                        name:'tom',
                        address:{
                            province:'安徽省',
                            city:'合肥市'
                        }
                    }

                    let obj2 = {
                        name:'tom',
                        address:{
                            province:'江苏省'
                        }
                    }
                    let obj = Object.assign(obj1,obj2);

                    console.log(obj); // { name: 'tom', address: { province: '江苏省' } }
                    
                    并不会出现如下所期望的结果
                    address:{
                        province:'江苏省',
                        city:'合肥市'
                    }
                    也就是说,obj1中的address是被完全替换掉的,这个现象叫做浅拷贝,
                    如果需要实现深拷贝,可以使用JSON.stringify或者第三方库(lodash)

                    let obj1 = {
                        name:'tom',
                        address:{
                            province:'安徽省',
                            city:'合肥市'
                        }
                    }

                    let obj2 = obj1;
                    let obj3 = JSON.parse(JSON.stringify(obj1));
                    let obj4 = Object.assign({},obj1);

                    obj1.address.city = '苏州市';

                    console.log('obj1',obj1); // 苏州市
                    console.log('obj2',obj2); // 苏州市
                    console.log('obj3',obj3); // 合肥市
                    console.log('obj4',obj4); // 苏州市

                    注意:如果对象中包含方法,使用JSON.stringify时,该方法会丢失
                    let obj1 = {
                        name:'tom',
                        address:{
                            province:'安徽省',
                            city:'合肥市',
                            sayAddress(){
                                console.log(111);
                            }
                        }
                    }
                    let obj3 = JSON.parse(JSON.stringify(obj1));
                    console.log(obj3); // { name: 'tom', address: { province: '安徽省', city: '合肥市' } }

        3. Object.setPrototypeOf(obj,prototype)
            将一个对象的原型(prototype)设置到另一个对象obj中
        
        4. Object.getPrototypeOf(obj)
            获取一个对象的原型(prototype)
            
            function Person(name){
                this.name = name;
            }

            Person.prototype.sayName = function(){
                console.log('你好');
            }

            var p1 = new Person();
            p1.sayName();

            function Dog(){

            }
            //ES5解决方案:子构造函数的原型指向父构造函数的实例,需要在实例创建之前
            //Dog.prototype = new Person();
            var dog1 = new Dog();
            //ES6解决方案:Object.setPrototypeOf
            Object.setPrototypeOf(dog1,Person.prototype);
            dog1.sayName();

            var res = Object.getPrototypeOf(dog1);
            console.log(res); // Person { sayName: [Function] }

        5. Object.keys(obj)
            键
            返回一个对象obj的可枚举属性名组成的数组
        6. Object.values(obj)
            值
            返回一个对象obj的可枚举属性值组成的数组
        7. Object.entries(obj)
            键值对
            返回一个对象obj的可枚举属性的键值对数组
        
            let obj = {
                name:'xpf',
                age:25,
                gender:'male'
            }

            console.log(Object.keys(obj)); // [ 'name', 'age', 'gender' ]
            console.log(Object.values(obj)); // [ 'xpf', 25, 'male' ]
            console.log(Object.entries(obj)); // [ [ 'name', 'xpf' ], [ 'age', 25 ], [ 'gender', 'male' ] ]
        
            用途:将一个对象转换为Map集合
                let obj = {
                    name:'xpf',
                    age:25,
                    gender:'male'
                }

                //let map = new Map(obj); // 直接放进去会报错
                let map = new Map(Object.entries(obj));
                console.log(map);

5、函数的扩展
    1) 函数简写
        1. 函数声明在对象中
            let obj = {
                name:'xpf',
                sayName:function(){
                    console.log(1);
                }
            }
            ===>等价于
            let obj = {
                name:'xpf',
                sayName(){
                    console.log(1);
                }
            }

        2. 函数声明在参数中(回调函数/匿名函数)
            forEach(function(){})
            setInterval(function(){},1000)

            ES6中允许使用箭头 => 定义函数  
                function(){}
                ===>等价于
                ()=>{}
            
            let fun1 = function(item){
                return item;
            }
            let fun2 = item => item;

            console.log(fun1);
            console.log(fun2);

            箭头函数可以根据参数个数来省略(),可以根据函数体内部代码的行数来省略{}
                一个参数时,可以省略()
                    item => {}
                不要参数或者多个参数时,不可以省略()
                    () => {}
                    (item,index) => {}

                函数体内部只有一行代码的时候,可以省略{}
                多行代码时,不可以省略{}

            案例一:
                let arr = [{
                    name:'xpf',
                    gender:'male'
                },{
                    name:'tom',
                    gender:'male'
                },{
                    name:'xiaohong',
                    gender:'female'
                }]

                let res1 = arr.filter(function(item){
                    return item.gender == 'female';
                })

                let res2 = arr.filter( (item)=>{
                    return item.gender == 'female';
                } )
                console.log(res1);
                console.log(res2);

            案例二:
                let obj = {
                    name:'xpf',
                    age:25,
                    sayName:()=>{
                        console.log(this.name);
                    },
                    sayAge:function(){
                        console.log(this.age);
                    }
                }
                obj.sayName(); // undefined
                obj.sayAge(); // 25

                注意:箭头函数中的this指向该箭头函数的外部函数
                    如果箭头函数外部没有函数,那么这个this就只想全局对象

            案例三:
                let obj = {
                    list:[1,2,3,4],
                    add(){
                        this.list.forEach(function(){
                            console.log(this.list); // undefined
                        })
                    }
                }
                obj.add();

                解决方案一:手动更改this
                    let obj = {
                        list:[1,2,3,4],
                        add(){
                            var that = this;
                            this.list.forEach(function(){
                                console.log(that.list)
                            })
                        }
                    }
                    obj.add();

                解决方案二:使用箭头函数
                    let obj = {
                        list:[1,2,3,4],
                        add(){
                            this.list.forEach(()=>{
                                console.log(this.list)
                            })
                        }
                    }
                    obj.add();

                    箭头函数的this先指向了外部的add函数,由于add函数被obj对象调用,所有add方法中的this指向了obj
                    最终,箭头函数中的this指向了obj

    2) 函数参数的默认值
        在ES6之前,一般无法为函数的参数提供默认值
            function sayName(name,age,gender){
                console.log(gender); // undefined
            }
            sayName(name,age)

            如何设置默认值?
                function person(name,age){
                    age = age || 15;
                    console.log(name,age);
                }
                person('xpf'); // xpf 15
                person('xpf',25); // xpf 25
                person('xpf',''); // xpf 15

        在ES6时,可以使用解构给函数参数提供默认值
            function sayName({name,age,gender='male'}){
                console.log(gender); // male
            }
            sayName({name,age})
        
        应用:
            1、ajax参数默认
            2、可以规定函数必须要传递某一个参数(即该参数不可省略)
                function throwErr(){
                    throw new Error('该参数不可被省略!')
                }

                function sayName({name = throwErr,age}){
                    console.log(name,age);
                }

                sayName({name:'xpf',age:25}); // xpf 25
                sayName({name:'xpf'}); // xpf undefined
                sayName({age:25}); // 抛出错误 25

 

 

你可能感兴趣的:(ES6课程学习笔记,es6/es7)