ES6常用语法

一、letconstvar

var:块级,容易污染全局
letconst:局部

1.1定义变量防止污染全局,因为他们输局部变量,var是块变量:
{
    let name = "yes"
    console.log(name) //yes
}
console.log(name) //window.name

1.2 for循环要使用let声明,因为这样每次循环式一个作用于,如果用var,那就是所有循环共享,const无法再for中使用,const修饰的变量
不能被修改

1.3 临时性死区
    console.log(color) //undefined
    var color = 'yellow'

    console.log(color) //报错error
    let color = 'yellow'

    console.log(color) //报错error
    const color = 'yellow'

【注】:es6中少用var,多用letconst,如果变量会被修改就用let,
不能修改就用const


二、箭头函数
var nums = [1,2];
 //普通写法
nums.map(function(number){
    return number + 1;
})
1、显示返回
//es6写法(删除function,在后面加“=>”)
nums.map((number)=>{
    return number + 1;
})
2、隐式返回(return删除、大括号删除)
nums.map((number)=>number + 1)


3、箭头函数中的this是继承父级的,以往都是使用:
    var _this = this;
    使用箭头函数就可以直接继承父级的使用this了:
    var obj = {
        name:'seven',
        hobbies:['coding','sleeping']
        printBhobbies:function(){
            this.hobbies.map((hobby)=>{
                //这里的this继承父级的this
                console.log(this.name+"-->"+hobby)
            })
        }
    }

4、对象、数组解构

5、forEach(注意"E"大写)for ofArray.prototype.fun = function() {
    console.log(99);
};
let arr = [3,4,5,6];
arr.font = 'wokao';

5.1 arr.forEach(number=>{
        console.log(number)//3,4,5,6
    })   
//forEach无法跳过和终止(continuebreak)

5.2 for(let index of arr){
        console.log(arr[index])//3,4,5,6,wokao,function(){}
    }

5.3 for(let number of arr){
    console.log(number)
    }
    //for of支持continuebreak,但是这样无法获取索引

    for(let [index,number] of arr.entries()){
        console.log(index,number)
    }
    //entries()js数组迭代接口,里面通过next调用下一个,这样就可以获取索引

//for of相对于for in遍历的直接是value而不是index,其次,for in 会遍历
数组上的属性,for of只会遍历其中value,**但是需要注意的是for of目前不支持对象**


6、Array.fromArray.of:
6.1 Array.from:方法从一个类似数组或可迭代对象(字符串、对象等)中创建一个新的数组实例。
Array.from(obj);
Array.from(array,row=>{row.name}))
6.2 Array.of(2,3,4444,5,5):将穿进去的参数转变为数组

7、剩余参数 ...data:
7.1 var arr = [1,2,3,4,5];
const {a,b,...c} = arr; //a:1 b:2 c:[3,4,5]

7.2 function aa(a,...b){
    console.log(a,b)
    }
    aa(1,2,3,4) //1 [2,3,4]

8、扩展参数
var nmn = ['a','b','c'];
var aba = ['f','n'];
var res = [...nmn,'e',...aba];//['a','b','c','e','f','n']


9、Promise:相当于一种承诺,不管怎样都会有一个结果。
9.1 对异步请求
//后一个请求依赖前一个请求,可以先定义前一个请求的promise,然后监听then,在then成功后在来第二个请求的promise,然后监听第二个请求的then
let username;
let usersPromise = axios.get('https://api.github.com/users');
usersPromise.then(response=>{
    username = response.data[0].login;
    return axios.get('https://api.github.com/users/'+username+'/repos');
}).then(response=>{
    console.log(response.data)
}).catch(error=>{
    //整个过程只要有错误就会进入此
    console.log(error.response)
})

9.2 写自己的promise:

 //成功就调用success数据,失败就调用error数据
const p = new Promise((success,failed)=>{
    // success(' seven is a  good boy!'); //reslove立即返回
    setTimeout(()=>{
        // success('seven is a superMan!');  //2s后执行完,进入then
        failed(Error('seven is a badboy!'));  //2s后进入catch,Error()可以抛出Promise中错误行,如果不加那就会显示catch下的错误行
    },2000)
});

p.then(data=>{
    console.log(data);
}).catch(error=>{
    console.error(error);
})


9.3 多个互不相干的promise可以使用Promise.all([p1,p2,..])

//多个promise,并且之间无关联,可以使用Promise.all()调用
const users = new Promise((success,failed)=>{
        setTimeout(()=>{
            success([
                {id:1,name:'张三'},
                {id:2,name:'李四'},
            ])
        },2000)

    })

const moves = new Promise((success,failed)=>{
        setTimeout(()=>{
            success([
                {id:1,name:'小兵张嘎'},
                {id:2,name:'举起手来'},
            ])
        },1000)

    })

console.log(Promise.all([users,moves])); //返回两个数组0:users的数据  1:moves的数据


10 Symbol :javascript推出的第七种数据类型

 10.1 解决对象中有相同key被覆盖情况:
     var obj = {
        [Symbol('user')]:{name:'张三',age:11},
        [Symbol('user')]:{name:'李四',age:15,sex:'男'},
    }
    console.log(obj);
//Symbol(user): {name: "张三", age: 11},Symbol(user): {name: "李四", age: 15, sex: "男"}


 10.2 Symbol不能被遍历:
     for(let index in obj){
         console.log(obj[index]);//啥也没有
    }

    通过js提供特殊接口获取Symbol数据:
    Object.getOwnPropertySymbols(obj);//获得一个Array

    提供四种遍历方法:
    Object.getOwnPropertySymbols(obj).map(sym=>{
        console.log(obj[sym]);
        console.log(obj[sym].name);
        console.log(obj[sym].age);
    });

    for(let sym of  Object.getOwnPropertySymbols(obj)){
        console.log(obj[sym]);
        console.log(obj[sym].name);
        console.log(obj[sym].age);
    }

    let newUserArr = Object.getOwnPropertySymbols(obj);
    for(let index in newUserArr){
        console.log(obj[newUserArr[index]]);
        console.log(obj[newUserArr[index]].name);
        console.log(obj[newUserArr[index]].age);
    }


    let userArr = Object.getOwnPropertySymbols(obj);
    userArr((sym,index)=>{
        console.log(obj[sym]);
        console.log(obj[sym].name);
        console.log(obj[sym].age);
    })


11 eslint
    11.1 安装
    npm install  eslint
    npm install -g eslint

    然后在命令行输入 
    eslint --init //初始化配置文件,选择Answer...
    ![这里写图片描述](http://img.blog.csdn.net/20180324111755055?watermark/2/text/aHR0cDovL2Jsb2cuY3Nkbi5uZXQvamo1NDY2MzA1NzY=/font/5a6L5L2T/fontsize/400/fill/I0JBQkFCMA==/dissolve/70/gravity/SouthEast)

    eslint bad-code.js //检查bad-code.js语法


    11.2 排查错误:
    语法查错位置:http://eslint.cn/docs/rules/
    将错误规则名字(如:semi)复制,来上面链接找对应解决办法。

    eslint bad-code.js --fix ; //eslint会自动修复一些错误

    11.3 配置规则:.eslintrc.json
    在.eslintrc.jsonrules中配置:
    {
        ....
        "global":{  //定义全局变量而不报错
            "Vue":true
        },
        "rules":{
            "no-console":"error" //off(0)warn(1)error(2)
        }
    }


    11.4 禁用eslint:
        1)模块级禁用:在该模块上方定义
        /* globals Vue */
        new Vue({...})
        2)区间内不用eslint限制:
         /*eslint-disable 规则名(no-console) */
             ....这中间的代码不受eslint限制....
          /*eslint-enable 规则名(no-console)*/



12 模块

    12.1 导出模块
    1)
      //单个命名导出
      export const apikey='xxx';
      //批量命名导出 
      const a = 1;
      const b = 2;
      export {a as A,b} //as重命名后,外面就要使用A
    2) //默认导出
      const apikey = 'yyy';  
      export default apikey; 

    //引用2)方式默认导出的,在引用可以随便命名,不是用{}
     import apikeysuibian from './config';
     //应用1)方式必须与导出名字相同并且要用{}
     import {apikey as Key} from './config';
    //如果导出一个模块下a(默认导出),b,c(b,c命名导出),引用:
    import a,{b,c} from './config'

    tips:
    [slug 插件]:将用户输入的emoji等都改为"-"连接
    npm install slug --save
    import slug from slug;
    let name = slug(name); 


13 Class改写prototype的继承

    13.1 类的定义
    1)class User{}
    2)const User = class{}

    class User{
        constructor(name,age){
            this.name = name;
            this.age = age;
        }

        //普通方法,通过实例调用
        info(){
            console.log(this.name + ',' +this.age)
        }

        //静态方法用static修饰,通过类调用
        static description(){
            conosle.log('我是静态方法')
        }

        //通过set赋值
        set github(value){
            this.githubName = value;
        }
        //通过get取值
        get github(){
            return this.this.githubName;
        }
    }
    const user = new User('张三',14);
    user.githubName = 'seven';//触发set github()
    console.log(user.githubName);//触发get github()

【注】:类中的方法与方法之间不能有",",与后端代码一样


    13.2 类的扩展
        1)类中的方法名称也可以使用计算属性
        const methodName = 'info';
        class User{
            [methodName](){
                return 'info method';
            }
        }


        2)类的继承

        es5类的继承:
            function Animal(name,age){
                this.name = name;
                this.age  = age;
            }
            function Dog(){
                Animal.call(this,name,age);
                this.name = name;
                this.age  = age;
            }
            Dog.prototype = new Animal();
            //由于原型指向了Animal,构造也会是Animal,所以要指回来
            Dog.prototype.constructor  = Dog();

        es6类的继承:
        class Animal{
            constructor(name,age){
                this.name = name;
                this.age = age;
            }
        }
        class Dog extends Animal{
            constructor(name,age){
                super(name,age);
                this.name = name;
                this.age = age;
            }
        }

        覆盖、重写:
        子类与父类方法名相同就覆盖了


14 迭代器
    var arr = [1,2,3];
    let iter = arr[Symbol.iterator]()
    iter.next() //1
    iter.next() //2
    ..

    实现数组返回valueindex迭代器:
    Array.prototype.values = function(){
        let i = 0;
        let items = this;
        return {
            next(){
                const done =  i >= items.length;
                const value = done ? undefined: items[i++];
                return {
                    done,
                    value
                }
            }
        }
    }

    let arr = [1,2,3];
    const iter = arr.values();
    console.log(iter.next());
    console.log(iter.next());
    console.log(iter.next());
    console.log(iter.next());

15 生成器Generator:
    15.1 生成器定义以及简单实用

    function* listColors(){
        yield
    }

    /* 1 返回规定值*/
    function* listColors(){
        yield 'red';
        yield 'yellow';
        yield 'green';
    }

    const color = listColors();
    color.next(); //red
    color.next(); //yellow
    color.next();//green

    /* 2 返回计算值*/
    function* number(){
        let i = 0;
        yield i;
        i++;
        yield i;
        i++;
        yield i;
        i++;
    }

    const n = number();
    console.log(n.next()) //0
    console.log(n.next()) //1
    console.log(n.next())//2


    /* 3 返回计算的数组*/
    function* loop(repos){
        for(const repo of repos){
            yield repo
        }
    }
    const arr = ['a','b','c','d','e'];
    const repoGen = loop(arr);
    for(let repo of repoGen){
        console.log(repo)
    }


    15.2 生成器控制ajax工作流
    function ajax(url){
    axios.get(url).then(res=>userGen.next(res.data));
    }

    function* steps(){
        const users = yield ajax('https://api.github.com/users');
        const firstUser = yield ajax('https://api.github.com/users/'+users[0].login);
        const followers = yield ajax(firstUser.followers_url);
    }

    const userGen = steps();
    userGen.next(); //初始化执行获取users那一步,然后通过ajax调用成功后,在调用userGennext(res.data),
                    //其中res.data返回后保存在const users中,然后才执行外面的next()而执行firstUser
                    //....



16 proxyproxy 重新定义对象默认属性、方法,没有改变的就默认还是用之前对象的,相当于代理模式
    16.1 proxy定义:
    const person = {name:"seven",age:23};
const personProxy = new Proxy(person, {
    get(target,key){ //personProxy.name 触发此方法
        //target:personProxy , key:name
        return target[name].toUpperCase();
    },
    set(target,key,value){ //personProxy.name = xxx 触发此方法
        //target:personProxy , key:name
        return target[name] = value;
    }

});
personProxy.name = 'good boy';
console.log(personProxy) //name: good boy ,age:23 
//proxy 就是改变某些对象默认属性、方法,没有改变的就默认还是用之前对象的,代理模式


    16.2 proxy实际应用:
    1)手机号码输出格式化
    const phoneHandler = {
        set(target,key,value){
            target[key] = value.match(/[0-9]/g).join('');
        },
        get(target, key){
            return target[key].replace(/(\d{3})(\d{4})(\d{4})/,'$1-$2-$3');
        }
    }
    const phoneNumber = new Proxy({},phoneHandler)
    phoneNumber.number = '13247629622';
    console.log(phoneNumber.number ); //132-4762-9622

17 set集合
    const fruits = new Set(['apple','pear']);
    const  colors = new Set(); 
    colors.add(1);
    colors.add('1');
    //set 无法通过索引获取,因为是无序的
    //set 重复值会被替换,但是字符串1与数字1是两种

    colors.delete('1') ;//删除某个元素
    colors.has('1');//是否存在
    colors.clear();//清除所有的set数据

    //遍历setforofforEach
    colors.forEach((value,key,curSets)=>{
        console.log(value) //第一个参数是value
        console.log(key) //第二个参数说是索引,但是set无序,为了与数组forEach保持一致key也设置了value的值
        console.log(curSet)//当前遍历的set集合
    })


    //set可以去重数组重复值
    const numbers = [1,1,1,2,3,4,4,4,5]; 
    const numbersSet = new Set(numbers);  //数组转set
    console.log(numbersSet);//Set(5) {1, 2, 3, 4, 5}
    const uniqueNumbers = [...numbersSet];  //set转数组利用扩展参数
    console.log(uniqueNumbers); //[1,2,3,4,5]


18 WeakSet
    18.1 与Set区别
    1)必须传入的都是对象:new WeakSet([{},{},...])
    2)内部没有next不是iterator,不可用forforEach循环
    3)相对于数组存储对象而言:
    数组:
    let obj1 = {'name':'aa',age:11};
    let obj2 = {'name':'bb',age:22};
    let arr = [obj1,obj2]
    obj1 = null;
    console.log(arr);
    //[{'name':'aa',age:11},{'name':'bb',age:22}] 

    WeakSet集合
    let obj1 = {'name':'aa',age:11};
    let obj2 = {'name':'bb',age:22};
    let weakSetData = new WeakSet([obj1,obj2]);
    obj1 = null;
    console.log(weakSetData);
    //obj1就不存在了

    【注】通过这一点可以判断引用是否被清除


19 Map

    const fruits = new Map([['apple',5],['banana',6]]);
    const map = new Map();
    const map = new Map();
    map.set('a',233);
    map.set('b',233);
    console.log(map);

    //map相对于对象来说,key可以是任意的(可以是对象)
    console.log(map.size);
    console.log(map.has('a'));
    map.delete('a');//删除
    map.clear(); //清空
    console.log(map.get('a'));//单独取某个值

    //可以通过forforEach循环
    map.forEach((value,key,map)=>{
        console.log(value);
        console.log(key);
        console.log(map);
    })

    for(let [key,value] of map){
        console.log(key)
        console.log(value)
    }

20 WeakMapmap区别:
        1)没有size属性
        2)没有clear方法
        3)不能通过for循环
        4)key必须是对象
        5)与WeakSet类似,如果内部对象没有被引用了,辣鸡回收机制就会回收该对象。


    let obj1 = {name:'zz'};
    let obj2 = {name:'yy'};

    let map1 = new Map();
    map1.set(obj1,'this is map1 obj1');
    map1.set(obj2,'this is map1 obj2');
    let map2 = new WeakMap();
    map2.set(obj1,'this is map2 obj1');
    map2.set(obj2,'this is map2 obj2');

    obj1 = null;

    console.log(map1);
    console.log(map2);

猜你喜欢

转载自blog.csdn.net/jj546630576/article/details/79254622