ES6新特性学习01

一、关于ES(x)

  1. ES全称为ECMAScript,是脚本语言的规范,而平时编写的javascript是ECMAScript的一种实现。所以ES新特性其实就是指的JavaScript新特性。
  2. 在2015年发布ES6,每年更新一版。
  3. ES6的重要意义:
    • ES6的版本变动内容最多,具有里程碑意义。
    • ES6中加入了许多新的语法特征,编程实现更加简单高效
    • ES6是前端发展的趋势,就业必备技能

二、ES6新特性

  1. let声明变量以及声明特性

    • 声明格式
      1
      2
      3
      4
      let a;
      let b,c,d;
      let f=100;
      let g=[],h="1234",s={};
    • let声明变量的特性
      • 变量不能重复声明(var声明可以重复)
      • 块级作用域,只能在块内有效(比如 if else for while等)
      • 不存在变量提升,不允许在变量声明之前使用变量
        1
        2
        3
        console.log(username);
        var username="fanda"; //输出undefined
        //如果使用let声明则会报错,不允许在变量声明之前使用变量
      • 不影响作用域链效果
        1
        2
        3
        4
        5
        6
        7
        {
        let age=19;
        function fn(){
        console.log("年龄:"+age);
        }
        fn(); //输出:年龄:18 ,需要与块作用域进行区分
        }
    • 运用let块级作用域的特性可以实现点击方块变色效果
      1
      2
      3
      4
      5
      6
             for(let i=0;i<btn.length;i++)
      {
      btn[i].onclick=function(){
      btn[i].style.background="pink"
      }
      }
  2. const定义常量(常量:值不能修改的量 )

    • 一定要赋初始值
    • 一般的常量需要使用大写(潜规则)
    • 常量的值不能进行修改
    • 块级作用域
    • 对于数组和对象的元素修改,不算做对常量的修改,不会报错
  3. ES6-变量的结构赋值

    • ES6允许按照一定模式从数组和对象中提取值,对变量进行赋值,这被称为解构赋值
    • 数组的解构赋值
      1
      2
      3
      4
      5
      6
      const F4=['张三','李四','王五','刘能'];
      let [z,l,w,n]=F4;
      console.log(z);
      console.log(l);
      console.log(w);
      console.log(n); //按顺序输出数组中的值
    • 对象的解构赋值
      1
      2
      3
      4
      5
      const zhao={name:"赵本山",age:65,xiaopin:function(){console.log("我可以演小品!")}}
      let {name,age,xiaopin}=zhao;
      console.log(name);
      console.log(age);
      console.log(xiaopin);
  4. ES6-模板字符串

    • 声明模板字符串
      1
      2
      let str=`这是一个模板字符串`;
      console.log(str,typeof str); //输出字符串和元素类型
    • 内容中可以直接出现换行符
      1
      2
      3
      4
      let str=`<ul>
      <li>用户名</li>
      <li>密码</li>
      <li>确认密码</li></ul>`;
    • 变量拼接
      1
      2
      3
      let username='fanda';
      let out=`${username}是天下无敌帅!`;
      console.log(out); //实现字符串的拼接
  5. ES6-简化对象

    • ES6允许在大括号中,直接写入变量和函数,作为对象的属性值和方法。
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      let username='fanda';
      function change(){
      console.log("我们可以改变!");
      }
      const obj={
      username,
      change,
      improve(){
      console.log("这是利用简便方法定义的函数!")
      }
      }
  6. ES6-箭头函数及其声明特点

    • ES6中允许使用【箭头】(=>)定义函数
    • 声明一个函数
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      //以前的写法
      let fn()=function(){
      //函数体内容
      }
      //箭头函数的写法
      let fn=(a,b)=>{
      // 函数体内容
      return a+b;
      }
      console.log(fn(2,5));
    • 箭头函数声明的特性:
      • this是静态的,始终指向函数声明时所在作用域下的this值
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
        11
        12
        13
        14
        15
        16
        17
           function getName(){
        console.log(this.name);
        }
        let getName2=()=>{
        console.log(this.name);
        }
        window.name="fanda";
        const school={
        name:'ASDFGH'
        }
        //普通调用函数
        getName();
        getName2();

        //call方法调用
        getName.call(school);
        getName2.call(school);
      • 不能作为构造函数实例化对象
      • 不能使用 arguments变量
      • 箭头函数的简写
        1
        2
        3
        4
        5
        6
        7
        8
        9
        //1)省略小括号,当形参有且只有一个时
        let add=n=>{
        return n+n;
        }
        console.log(add(9)); //输出18
        //2)省略花括号,当代码体只有一条语句时,此时return也必须省略。
        //而且语句的执行结果就是函数的返回值。
        let pow=n=>n*n;
        console.log(pow(9)); //输出结果为81
    • 箭头函数的一般使用场景
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
       	const arr=[1,6,7,10,20,50,100];  //选中偶数
      const result=arr.filter(function(item){
      if(item%2==0){
      return true;
      }else{
      return false;
      }
      })
      console.log(result);
      // 使用箭头函数简化操作
      const result=arr.filter(item=>item%2===0);
      console.log(result);
      • 箭头函数适合与 this无关的回调,定时器,数组的方法回调。
      • 箭头函数不适合与 this有关的回调,事件回调,对象的方法。
  7. ES6-函数参数默认值

    • 形参初始值(具有默认值的参数一般位置靠后)
      1
      2
      3
      4
      5
       function add(a,b,c=10){
      return a+b+c;
      }
      console.log(add(1,2,3)); //输出6
      console.log(add(1,2)); //输出13
    • 默认值可以与解构赋值一起使用
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
        function connect({host,username,password,port="8000"}){
      console.log(host);
      console.log(username);
      console.log(password);
      console.log(port);
      }
      connect({
      host:'www.baidu.com',
      username:'root',
      password:'root',
      prot:'3306'
      })
  8. ES6-rest参数

    • rest参数用于获取函数的实参,用来代替arguments。注:rest参数必须放在其他参数最后
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      //ES5中的arguments
      function date(){
      console.log(arguments); //是对象类型
      }
      date("abc","张三")
      //ES6中rest参数
      function date2(...args){
      console.log(args);
      }
      date2("abc","张三"); //数据类型是数组
  9. ES6-扩展运算符

    • […] 扩展运算符能将【数组】转换为 逗号隔开的参数序列
      1
      2
      3
      4
      5
      6
       const user=["张三","李四","王五"];
      function myname(){
      console.log(arguments);
      }
      nyname(user); //直接输出数组
      myname(...user); //输出一个对象包含三个元素
    • 扩展运算符的运用:数组合并
      • 数组合并,ES5的方法可以用concat()方法
        1
        2
        3
        4
        5
          const arr1=["张三","李四"];
        const arr2=["小红","小王"];
        // const arr=arr1.concat(arr2);
        const arr=[...arr1,...arr2];
        console.log(arr);
      • 数组克隆
        1
        2
        3
          const arr1=["张三","李四"];
        const arr2=[...arr1];
        console.log(arr2);
      • 将伪数组转换为真正的数组
  10. ES6-Symbol数据类型

    • ES6引入了一种新的原始数据类型Symbol,表示独一无二的值。是一种类似于字符串的数据类型
    • Symbol特点:
      • Symbol的值是唯一的,用来解决命名冲突问题;
      • Symbol值不能与其他数据类型进行运算;
      • Symbol定义的对象属性不能使用for…in循环遍历,但是可以使用Reflect.ownKeys来获取对象所有键名。
        1
        2
        3
        4
        5
        6
        7
        8
        9
        10
            //创建symbol
        let s=Symbol();
        console.log(s,typeof s);
        let s1=Symbol("李四");
        let s2=Symbol("李四");
        console.log(s1==s2); //返回false
        //Symbol.for()创建
        let s3=Symbol.for("张三");
        let s4=Symbol.for("张三");
        console.log(s3==s4); //返回true
    • 对象添加Symbol类型的属性
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
      27
      28
      29
      30
      31
      32
        //对象扩展方法,当不知道对象中具有哪些属性和方法时
      let game={
      name:"狼人杀",
      number:12,
      up:22,
      down:"下降"
      }
      //自定义对象
      let methods={
      up:Symbol(),
      down:Symbol()
      }
      //对象扩展方法
      game[methods.up]=function(){
      console.log("我可以向上");
      }
      game[methods.down]=function(){
      console.log("我可以向下");
      }
      console.log(game);

      //第二种方法
      let photo={
      name:"天空",
      [Symbol('say')]:function(){
      console.log("我可以说话");
      },
      [Symbol('see')]:function(){
      console.log("我可以看见")
      }
      }
      console.log(photo);
    • Symbol内置值,除了定义自己使用的Symbol值外,ES6还提供了11个内置的Symbol值,指向语法内部使用的方法。
      方法 描述
      Symbol.hasInstance 当其他对象使用instanceof运算符,判断是否为该对象的实例时,会调用这个方法
      Symbol.isConcatSpreadable 对象的Symbol.isConcatSpreadable属性等于的是一个布尔值,表示该对象用于Array.prototype.concat()时,是否可以展开
      Symbol.unscopables 该对象指向使用with关键字时,哪些属性会被with环境排除
      Symbol.match 当执行str.match(myObject)时,如果该属性存在,会调用它,返回该方法的返回值
      Symbol.replace 当该对象被str.replace(myObject)方法调用时,会返回该方法的返回值
      Symbol.search 当该对象被str.search(myObject)方法调用时,会返回该方法的返回值
      Symbol.split 当该对象被str.split(myObject)方法调用时,会返回该方法的返回值
      Symbol.iterator 对象进行for…of循环时,会调用此方法,返回对象的默认遍历器
      Symbol.toPrimitive 该对象被转为原始类型的值时,会调用这个方法返回该对象对应的原始类型值
      Symbol.toStringTag 当该对上面调用tostring方法时,会返回该方法的返回值
      Symbol.species 创建衍生对象时,会使用该属性
  11. ES6-迭代器

    • 迭代器(iterator)是一种接口,为各种不同的数据类型提供统一的访问机制。任何数据结构只要部署到Iterator接口上,就可以完成遍历操作。
    • ES6创建了一种新的遍历命令for...of循环,Iterator接口主要提供for…of消费。
    • 原生具备iterator接口的数据(可用for…of遍历),Array , Arguments , Set , Map , String , TypedArray , NodeList
    • 工作原理:
      • 创建一个指针对象,指向当前数据结构的起始位置。
      • 第一次调用对象的next方法指针自动指向数据结构的第一个成员。
      • 接下来不断调用next方法,指针一直往后移动,指到指向最后一个成员。
      • 每次调用next方法返回一个包含value和done属性的对象。
        1
        2
        3
        4
        5
        6
          const xiyou=["唐僧","孙悟空","猪八戒","沙僧"];
        let iter=xiyou[Symbol.iterator](); //创建指针
        console.log(iter.next());
        console.log(iter.next());
        console.log(iter.next());
        console.log(iter.next());
        运行返回结果
    • 迭代器的运用,自定义遍历对象
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
         //定义对象
      const obj={
      major:"软件工程",
      stus:["小红","小李","小张","小华"], //对象中包含数组
      [Symbol.iterator](){ //创建一个指针对象
      let index=0;
      _this=this;
      return{
      next:function(){ //此处运用箭头函数可以直接使用this
      if(index<_this.stus.length){
      const res={value:_this.stus[index],done:false}
      index++;
      return res;
      }else{
      return {value:undefined,done:true}
      }
      }
      }
      }
      }
      //通过for...of遍历得出对象中数组的值
      for(let v of obj){
      console.log(v); //输出 "小红","小李","小张","小华"
      }
  12. ES6-生成器函数声明与调用

    • 生成器函数是ES6提供的一种异步编程解决方案,语法行为和传统函数完全不同
    • 生成器函数的声明与调用
      1
      2
      3
      4
      5
        function * fn(){
      console.log("生成器函数");
      }
      let iterator=fn();
      console.log(iterator.next()); //以迭代器的形式输出内容
    • 生成器函数的参数传递(实现异步编程)
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
        function * fn(arg){
      console.log(arg); //打印出“AAA” (最先显示)
      let one=yield 111;
      console.log(one); //打印出“BBB” (第三显示)
      let two=yield 222;
      console.log(two); //打印出“CCC”
      }
      let iterator=fn("AAA");
      // next()方法传参,参数将作为上一个yield语句的返回结果(实现异步编程)
      console.log(iterator.next()); // 打印出迭代第一个对象{value:111,done:false} (第二显示)
      console.log(iterator.next("BBB")); // 打印出迭代第二个对象{value:222,done:false}
      console.log(iterator.next("CCC")); // 打印出迭代第三个对象{value:undefined,done:true}
    • 实现异步请求的案例
      1
      2
      3
      4
      5
      6
      7
      8
      9
      10
      11
      12
      13
      14
      15
      16
      17
      18
      19
      20
      21
      22
      23
      24
      25
      26
       //实现1s后输出111,2s后输出222,3s后输出333
      function one(){
      setTimeout(()=>{
      console.log(111);
      iterator.next(); //调用函数
      },1000)
      }
      function two(){
      setTimeout(()=>{
      console.log(222);
      iterator.next(); //调用函数
      },2000)
      }
      function three(){
      setTimeout(()=>{
      console.log(333);
      },3000)
      }
      //生成器函数
      function * fn(){
      yield one(),
      yield two(),
      yield three()
      }
      let iterator=fn();
      iterator.next(); //初始调用函数