ES6

作者: 郭少华 | 来源:发表于2018-06-05 16:52 被阅读43次

    ES6的开发环境搭建

    现在的Chrome浏览器已经支持ES6了,但是有些低版本的浏览器还是不支持ES6的语法,这就需要我们把ES6的语法自动的转变成ES5的语法。Webpack是有自动编译转换能力的,除了Webpack自动编译,我们还可以用Babel来完成。这节课我们就使用Babel把ES6编译成ES5

    新建目录

    建工程目录之后创建两个文件夹:src和dist

    • src:书写ES6代码的文件夹,写的js程序都放在这里。
    • dist:利用Babel编译成的ES5代码的文件夹,在HTML页面需要引入的时这里的js文件。

    编写index.html

    <html>
    <head>
        <meta charset="utf-8" />
        <meta http-equiv="X-UA-Compatible" content="IE=edge">
        <title>Page Title</title>
        <meta name="viewport" content="width=device-width, initial-scale=1">
        <!--注意这里js路径是dist编译成ES5的js文件路径-->
        <script src="../dist/index.js"></script>
    </head>
    <body>
        Hello  Es6
    </body>
    </html>
    

    编写index.js

    在src目录下,新建index.js用ES6声明方式

    let a=1;
    console.log(a);
    

    初始化项目

    在cmd命令窗口初始化项目-y代表全部默认同意,就不用一次次按回车了。命令执行完成后,会在项目根目录下生产package.json文件。

    npm init -y
    

    全局安装Babel-cli

    npm install babel-cli  -g 
    

    本地安装babel-preset-es2015 和 babel-cli

    npm install  babel-preset-es2015 babel-cli --save-dev
    

    新建.babelrc

    在根目录下新建.babelrc文件,并打开录入下面的代码

    {
        "presets":[
            "es2015"
        ],
        "plugins":[]
    }
    

    现在可以在终端输入转换命令可以发现dist目录下已经生成了ES5语法的js文件

    babel src/index.js -o dist/index.js
    

    简化转换命令

    可以使用npm run build 直接利用webpack进行打包,在这里也希望利用这种方式完成转换。打开package.json文件,把文件修改成下面的样子。

    {
      "name": "es6test",
      "version": "1.0.0",
      "description": "",
      "main": "index.js",
      "scripts": {
        "build": "babel src/index.js -o dist/index.js"
      }
    

    修改好后,以后我们就可以使用 npm run build 来进行转换了。

    新的声明方式

    var 声明

    var 在ES6里是全局变量

    var a=2;
    {
       var a=3;
    }
    console.log(a); //打印出来是3
    

    let局部声明

    var a=2;
    {
       let a=3;
    }
    console.log(a);//打印出来是2
    

    var 声明的循环

    for(var i=0;i<10;i++){
      console.log('循环体中:'+i);
    }
      console.log('循环体外:'+i);
    

    你会发现循环体外的i变量被污染了,如果在外部再使用i时就会出现问题,这是开发者不想看到的。我们再利用let声明,就可以解决这个问题。

    用let声明的循环

    for(let i=0;i<10;i++){
      console.log('循环体中:'+i);
    }
      console.log('循环体外:'+i);
    

    你执行时会发现控制台报错了,找不到循环体外的i变量。通过两种声明的比较,可以明白let在防止程序数据污染上还是很有用处的。我们要努力去习惯用let声明,减少var声明去污染全局空间,在vue的使用中也要注意这点。

    const声明常量

    const a="aaa";
    var a='bbb';
    console.log(a);
    

    在编译这段代码的过程中,你就会发现已经报错,无法编译了,原因就是我们const声明的变量是不可以改变的。

    变量的解构赋值

    数组的解构赋值

    //ES5写法
    let a=0;
    let b=1;
    let c=2;
    //ES6写法
    let [a,b,c]=[1,2,3];
    console.log(a);
    console.log(b);
    console.log(c);
    

    数组模式和赋值模式统一

    等号左边和等号右边的形式要统一,如果不统一解构将失败。

    let [a,[b,c],d]=[1,[2,3],4];
    

    解构的默认值

    let [foo = true] =[];
    console.log(foo); //控制台打印出true
    

    现在我们对默认值有所了解,需要注意的是undefined和null的区别。

    let[a="aa"]=[undefined];
    console.log(a); //控制台显示aa
    
    let[a="aa"]=[null];
    console.log(a); //控制台显示null
    

    null相当于有值,但值为null。所以b并没有取默认值,而是解构成了null。

    对象的解构赋值

    let {name,sex}={name:'lm',sex:'男'}
    console.log(name+sex);
    

    圆括号的使用

    如果在解构之前就定义了变量,这时候你再解构会出现问题。下面是错误的代码,编译会报错。

    let name;
    {name}={name:'lm'}
    console.log(name);
    

    要解决报错,使程序正常,我们这时候只要在解构的语句外边加一个圆括号就可以了。

    let name;
    ({name}={name:'lm'})
    console.log(name);
    

    字符串解构

    const [a,b,c,d,e]="guosh";
    console.log(a);
    console.log(b);
    console.log(c);
    console.log(d);
    console.log(e);
    

    扩展运算符和rest运算符

    对象扩展运算符(…)

    当编写一个方法时,我们允许它传入的参数是不确定的。这时候可以使用对象扩展运算符来作参数,看一个简单的列子

    function sj(...arg){
        console.log(arg[0]);
        console.log(arg[1]);
        console.log(arg[2]);
        console.log(arg[3]);
    }
    sj(1,2,3,)
    

    这时我们看到控制台输出了 1,2,3,undefined,这说明是可以传入多个值,并且就算方法中引用多了也不会报错

    扩展运算符的用处

    var arr1 = [0, 1, 2];  
    var arr2 = [3, 4, 5];  
    arr1.push(...arr2);
    console.log(arr1) //结果 0,1,2,3,4,5
    

    rest运算符

    对象扩展运算符,rest运算符并它们有很多相似之处,不用特意去区分。它也用…(三个点)来表示。

    function gsh(first,...arg){
        console.log("first="+first); //结果是0
        console.log("arg="+arg);//结果是1,2,3,4,5,6,7
    }
    gsh(0,1,2,3,4,5,6,7)
    

    字符串模板

    字符串模板使用

    字符串拼接

    //ES5语法
    let a="姓名"
    let c="我的"+a+"LM";
    console.log(c);
    //ES6语法
    let a="姓名"
    let c=`我的${a}LM`;
    console.log(c);
    

    对html标签支持

    let a="姓名"
    let c=`<b>我的${a}LM<b>`;
    console.log(c);
    

    字符串查找

    includes判断是否存在

    let a="姓名"
    let c="我的姓名";
    document.write(c.includes(a));  //true
    

    startsWith判断开头是否存在

    let a="姓名"
    let c="我的姓名";
    document.write(c.startsWith(a));  //false
    

    endsWith判断结尾是否存在

    let a="姓名"
    let c="我的姓名";
    document.write(c.endsWith(a));  //true
    

    赋值字符串

    document.write('Guo|'.repeat(3)); //会打印三遍Guo|
    

    ES6数字操作

    二进制八进制声明

    //二进制开始是0第二个是B开头
    let a=0B010101;
    console.log(a); //打印21
    //八进制开始是0第二个是O开头
    let b=0O666
    console.log(b)//打印438
    

    数字验证

    Number.isFinite( xx )数字验证

    可以使用Number.isFinite( )来进行数字验证,只要是数字,不论是浮点型还是整形都会返回true,其他时候会返回false。

    let a=1;
    console.log(Number.isFinite(a))//true
    console.log(Number.isFinite(''呵呵))//false
    

    NaN验证

    console.log(Number.isNaN(NaN)); //true
    

    整数验证

    let a=123.1;
    console.log(Number.isInteger(a)); //false
    

    整数转换Number.parseInt(xxx)和浮点型转换Number.parseFloat(xxx)

    let a='9.18';
    console.log(Number.parseInt(a)); 
    console.log(Number.parseFloat(a));
    

    整数安全范围

    最大安全整数

    console.log(Number.MAX_SAFE_INTEGER);
    

    最小安全整数

    console.log(Number.MAX_SAFE_INTEGER);
    

    安全整数判断isSafeInteger( )

    let a= Math.pow(2,53)-1;
    console.log(Number.isSafeInteger(a));//false
    

    ES6中的数组

    JSON数组格式转换

    //0,1,2,是下标 length是长度
    let json={
        "0":"AA",
        "1":"BB",
        "2":"CC",
        length:3
    }
    
    let arr=Array.from(json);
    console.log(arr);
    

    这就是一个标准的JSON数组格式,跟普通的JSON对比是在最后多了一个length属性。只要是这种特殊的json格式都可以轻松使用ES6的语法转变成数组

    Array.of()方法

    let a=Array.of('A','B','C');
    console.log(a);
    

    它负责把一堆文本或者变量转换成数组

    find( )实例方法:

    • value:表示当前查找的值。
    • index:表示当前查找的数组索引。
    • arr:表示当前数组。
    var arr = [1, 2, 3, 4, 5, 6, 7, 8, 9];
    console.log(arr.find(function (value, index, arr) {
        return value > 5;
    }));
    

    控制台输出了6,说明找到了符合条件的值,并进行返回了,如果找不到会显示undefined。

    fill()实例方法

    fill()也是一个实例方法,它的作用是把数组进行填充,它接收三个参数,第一个参数是填充的变量,第二个是开始填充的下标位置,第三个是填充到的具体位置。

    let arr=[1,2,3,4,5,6,7,8,9];
    arr.fill('a',4,9);
    console.log(arr); //结果 [1, 2, 3, 4, "a", "a", "a", "a", "a"]
    

    数组的遍历

    for…of循环

    输出值
    let arr=['AA','BB','CC'];
    for (let item of arr) {
       console.log(item) 
    }
    
    输出数组索引
    let arr=['AA','BB','CC'];
    for (let item of arr.keys()) {
       console.log(item) 
    }
    
    输出索引和值
    let arr=['AA','BB','CC'];
    for (let [index,value] of arr.entries()) {
       console.log(index+value) 
    }
    

    entries( )实例方法

    entries()实例方式生成的是Iterator形式的数组,那这种形式的好处就是可以让我们在需要时用next()手动跳转到下一个值。我们来看下面的代码:

    let arr=['AA','BB','CC'];
    let list=arr.entries();
    console(list.next().value);
    console(list.next().value);
    console(list.next().value);
    

    ES6中的箭头函数和扩展

    ES5写法

    function add(a,b){
        return a+b;
    }
    console.log(add(2,3));
    

    ES6写法

    var add=(a,b)=>a+b;
    console.log(add(1,2));
    

    在箭头函数中,方法体内如果是两句话,那就需要在方法体外边加上{}括号。例如下边的代码就必须使用{}.

    var add=(a,b)=>{
    console.log("AAA")
      return a+b;
    };
    console.log(add(1,2));
    

    ES6中的函数和数组补漏

    对象的函数解构

    let json={
        name:'xm',
        age:'18'
    }
    function fun({name,age}){
        console.log(name);
        console.log(age);
    }
    fun(json);
    

    数组的函数解构

    let arr = ['a','b','c'];
    function fun(a,b,c){
        console.log(a,b,c);
    }
     
    fun(...arr);
    

    in是用法

    对象判断

    let obj={
        name:'xm',
        age:'18'
    }
    console.log('name' in obj) //true
    

    数组判断

    let arr=[,,]
    console.log(0 in arr) //false
    let arr1=['a','b']
    console.log(0 in arr1) //true
    

    注意:这里的0指的是数组下标位置是否为空

    数组的遍历方法

    forEach

    let arr=['aa',,'cc']
    arr.forEach((value,index) => {
        console.log(value,index) //结果aa 0 aa 2
    });
    

    forEach循环的特点是会自动省略为空的数组元素,相当于直接给我们筛空了。

    filter

    let arr=['aa',,'cc']
    arr.filter(x => {
        console.log(x)
    });
    

    some

    let arr=['aa',,'cc']
    arr.some(x => {
        console.log(x)
    });
    

    map

    let arr=['aa','bb','cc']
     console.log(arr.map(x=>'web'))  // 'web' 'web' 'web'
    

    map在这里起到一个替换的作用

    数组转换字符串

    toString()方法

    let arr=['aa','bb','cc']
    console.log(arr.toString())
    

    join方法

    let arr=['aa','bb','cc']
    console.log(arr.join('|'))  //自定义分隔符 aa|bb|cc
    

    ES6中对象

    对象赋值

    let name="XM";
    let age="18";
    let obj={name,age};
    console.log(obj) //{name: "XM", age: "18"}
    

    对象Key值构建

    有时候我们会在后台取出key值,而不是我们前台定义好的,这时候我们如何构建我们的key值那。比如我们在后台取了一个key值,然后可以用[ ] 的形式,进行对象的构建。

    let key="name"
    let obj={
        [key]:'XM'
    }
    console.log(obj); //{name: "XM"}
    

    Object.is( ) 对象比较

    let a={name:'XM'};
    let b={name:'XM'};
    console.log(a.name === b.name);
    //ES6比较方法
    let a={name:'XM'};
    let b={name:'XM'};
    console.log(Object.is(a.name,b.name));
    

    区分=== 和 is方法的区别是什么,看下面的代码输出结果。

    console.log(+0 === -0);  //true
    console.log(NaN === NaN ); //false
    console.log(Object.is(+0,-0)); //false
    console.log(Object.is(NaN,NaN)); //true
    

    ===为同值相等,is()为严格相等

    Object.assign( )合并对象

    let a={name:'XM'};
    let b={age:'18',sex:'男'};
    let c=Object.assign(a,b);
    console.log(c); //{name: "XM", age: "18", sex: "男"}
    

    Symbol在对象中的作用

    Symbol的声明

    var a=Symbol("ES6");
    console.log(a);
    console.log(a.toString());
    

    Symbol再对象中的应用

    var xm=Symbol();
    var obj={
        [xm]:'ES6'
    }
    console.log(obj[xm]); //ES6
    

    Symbol对象元素的保护作用

    没有进行保护的写法:

    var obj={name:'ES6',sex:'男',age:'18'}
    for(let item in obj){
        console.log(obj[item]); //ES6 男  18
    }
    

    现在我不想别人知道我的年龄,这时候我就可以使用Symbol来进行循环保护。

    var obj={name:'ES6',sex:'男'}
    var age=Symbol();
    obj[age]='18';
    for(let item in obj){
        console.log(obj[item]); //ES6 男
    }
    

    Set和WeakSet数据结构

    Set的声明

    Set和Array 的区别是Set不允许内部有重复的值,如果有只显示一个,相当于去重。虽然Set很像数组,但是他不是数组。

    let setArr=new Set(['aa','bb','cc','aa']);
    console.log(setArr); //aa,bb,cc
    

    Set值的增删查

    追加add

    let setArr=new Set(['aa','bb','cc','aa']);
    setArr.add('dd');
    console.log(setArr)//aa,bb,cc,dd
    

    删除delete

    let setArr=new Set(['aa','bb','cc','aa']);
    setArr.delete('aa');
    console.log(setArr)//bb,cc
    

    查找has

    let setArr=new Set(['aa','bb','cc','aa']);
    console.log(setArr.has('aa'));//true
    

    清空clear

    let setArr=new Set(['aa','bb','cc','aa']);
    setArr.clear();
    console.log(setArr);
    

    Set循环

    let setArr=new Set(['aa','bb','cc','aa']);
    for (let item of setArr) {
        console.log(item);
    }
    

    WeakSet的声明

    let weakObj=new WeakSet();
    let obj={
        name:"XM",
        age:"18"
    };
    weakObj.add(obj);
    console.log(weakObj);
    

    这里需要注意的是,如果你直接在new 的时候就放入值,将报错,只能通过add()插入

    let weakObj=new WeakSet();
    let obj={
        name:"XM",
        age:"18"
    };
    let obj1=obj;
    weakObj.add(obj);
    weakObj.add(obj1);
    console.log(weakObj);
    

    内存空间相同只会插入一个对象

    map数据结构

    map声明

    let obj={
        name:"XM",
        age:"18"
    };
    let map=new Map();
    map.set("a",obj);
    map.set("b",1);
    console.log(map);
    

    取值get

    console.log(map.get("b"));
    

    删除delete

    map.delete("b")
    

    根据key删除值

    size属性

    console.log(map.size);
    

    查找是否存在has

    console.log(map.has('a'))//true
    

    清除所有元素clear

    map.clear()
    

    用Proxy进行预处理

    get属性与set属性

    let pro =new Proxy({
        add: function(val){
            return val+10
        },
        name: 'gg'
    },{
        //get属性是在你得到某对象属性值时预处理的方法 target:目标值。key:目标的Key值。
        get: function(target,key,property){
            return target[key];
        },
        //set属性是值你要改变Proxy属性值时,进行的预先处理的方法 target:目标值。key:目标的Key值。value:要改变的值。receiver:改变前的原始值。
        set: function(target,key,value,receiver){
            return target[key] = value;
        }
    })
    
    console.log(pro); //触发get
    pro.name='aaa'; //触发set
    console.log(pro);
    

    apply的使用

    apply的作用是调用内部的方法,它使用在方法体是一个匿名函数时。

    let target = function () {
        return 'Hello';
    };
    var handler = {
        apply(target, ctx, args) {
            console.log('do apply');
            return Reflect.apply(...arguments);
        }
    }
    
    var pro = new Proxy(target, handler);
    console.log(pro());
    

    promise对象的使用

    promise执行多步操作非常好用

    let state=1;
    
    function step1(resolve,reject){
        console.log('1.开始-第一步');
        if(state==1){
            resolve('第一步--完成');
        }else{
            reject('第一步--出错');
        }
    }
    
    
    function step2(resolve,reject){
        console.log('2.开始-第二步');
        if(state==1){
            resolve('第二步--完成');
        }else{
            reject('第二步--出错');
        }
    }
    
    
    function step3(resolve,reject){
        console.log('3.开始-第三步');
         if(state==1){
            resolve('第三步--完成');
        }else{
            reject('第三步-出错');
        }
    }
    
    new Promise(step1).then(function(val){
        console.log(val);
        return new Promise(step2);
    }).then(function(val){
         console.log(val);
        return new Promise(step3);
    }).then(function(val){
        console.log(val);
        return val;
    });
    

    class类的使用

    类的声明

    class Coder{
        //类中的方法
        name(val){
            console.log(val);
        }
    }
    
    let guo=new Coder();
    guo.name('AA')
    

    类的多方法声明

    class Coder{
        //类中的方法
        name(val){
            console.log(val);
            return val;
        }
        skill(val){
            console.log(this.name("aa")+":"+"skill:"+val)
        }
    }
    
    let guo=new Coder();
    guo.skill('bb');
    

    类的传参

    class Coder{
        constructor(a,b){
            this.a=a;
            this.b=b;
        }
        add(){
            return this.a+this.b;
        }
    }
    let guo=new Coder(1,2);
    console.log(guo.add())
    

    我们用constructor来约定了传递参数,然后用作了一个add方法,把参数相加

    类的继承

    class Htmlel extends Coder{
    }
    let guo=new Htmlel();
    

    模块化操作

    • export :负责进行模块化,也是模块的输出
    • import : 负责把模块引,也是模块的引入操作

    export的用法

    我们新建一个temp.js文件,然后在文件中输出一个模块变量

    export var a='guo';
    

    然后可以在index.js中以import的形式引入

    import {a} from './temp.js'
    
    console.log(a);
    

    多变量的输出

    var a='guo';
    var b='guoa';
    var c='guob';
    export {a,b,c}
    

    函数的模块化输出

    export function add(a,b){
        return a+b;
    }
    

    as的用法

    有些时候我们并不想暴露模块里边的变量名称,而给模块起一个更语义话的名称,这时候我们就可以使用as来操作。

    var a='guo';
    var b='guoa';
    var c='guob';
    export {
        a as x,
        b as c,
        c as v
    }
    

    export default的使用

    加上default相当是一个默认的入口。在一个文件里export default只能有一个。我们来对比一下export和export default的区别

    export

    export var a ='guo';
    

    对应导入方式

    import {a} form './temp';
    

    export defalut

    export var a ='guo';
    

    对应导入方式

    import str from './temp';
    

    相关文章

      网友评论

        本文标题:ES6

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