2020.9.21陈悦玲

ES6

模板字符串

  • 模板字符串格式
var age = 33;
var str= = `我叫陈哥`
console.log(`我叫陈哥,今年${age}`)
  • 模板字符串特点

    let

  • 什么是let?
    let用于代替var,用于声明变量的新关键词,不会存在变量提升

  • var的两个缺点

  • 变量声明提前,打乱了程序正常的执行顺序

  • 没有块级作用域,代码块内的变量,会影响块外的变量

  • 变量提升举例

for(let i = 0;i<10;i++){
    console.log(i)//0-9
}
console.log(i)//报错
//以后写程序都用let不用var 只要声明变量都用let代替var
  • let原理
  • let会被自动翻译为匿名函数自调
  • 双保险,let为了进一步避免可能的冲突将变量悄悄改了名字:let t = 0 —> let _t = 0;

  • let特点

  • 全局写let t=0,用window.t却找不到

  • 同一级作用域内,不能在 let t=0 前,提前使用t。即使外层作用域有t变量,也不行

  • 相同作用域内,不允许重复let同一个变量

  • 注意事项:let有个兄弟const,专门用于声明一个值不能修改的常量。同时也具有let的特点,不会被声明提前,添加了块级作用域

  • 案例:

//第一步获得button按钮
    var btn = document.getElementsByTagName("button");
    // 用var
    //{}并不是块级作用域,全局依然可以找到
    //使用var声明的变量时在全局下,当我们开始找的时候,就已经在全局之下执行完成for循环了
    for(var i=0;i<btn.length;i++){
      btn[i].onclick=function(){
        console.log(`点击了第${i+1}个按钮`)
      }
    }
    // 用let
    for(let j=0;j<btn.length;j++){
      btn[j].onclick=function(){
        console.log(`点击了第${j+1}个按钮`)
      }
    }

箭头函数

  • 箭头函数如何使用
  • 去掉 function,在 () 和 {} 之间加 =>
  • 当形参只有一个的时候可以省略()
  • 当函数内部是return时,可以省略return不写
  • 当函数内部只有一条语句时,可以省略{}(就像if语句省略{}一个道理)

  • 数组排序

    //funtion(){}
    var arr = [1,2,5,3,4,6];
    arr.sort((a,b)=>{
    return a-b
    })
    //当只有一个参数的时候可以省略()
    console.log(arr)
  • 简化:

 //箭头函数
    function show(a){
      a(1)
    }
    // show(function(b){
    //   console.log(b)
    // })
    //简化
    // show((b)=>{
    //   console.log(b)
    // })
    //简化
    show(a=>console.log(b))
  • 什么时候使用?
    几乎所有回调函数都可以用 => 来简化
    注意:一定要记得去掉结尾的分号

    • 箭头函数的问题:
      箭头函数是一把双刃剑,箭头函数内外this是相通的。如果希望函数内外的this保持一致时,可以不用bind()换,而直接改为箭头函数即可。如果不希望函数内外的this一致,就是希望内部的this和外部的this不一样时,不能改为箭头函数
//this->window
var lilei={   //不是作用域
   sname: "Li Lei",
   friends:["欣欣","峰峰","丁丁"],
   // say:function(){
   say(){
     // 今后ES6中所有对象的方法不用加":function"
       // 但是这个简写不改变this,绝不等于箭头函数
       // Li Lei认识欣欣
       // Li Lei认识峰峰
       // Li Lei认识丁丁
       // 遍历lilei好友列表中每个朋友
       this.friends.forEach(
            // function(f){console.log(`${this.sname}认识${f}`)}
            //函数内的this指向window,用bind改变this的指向
            f=>console.log(`${this.sname}认识${f}`)
           // 希望this和say中的this保持一致都指lilei
    )
  }
}
lilei.say();
var button = document.getelementbyid("button")
button.addEventListener(functon(){
    console.log(this)
    }//this指向button
button.addEventListener(()=>{
    console.log(this)
    }//this指向window

for of

var li = document.querySelectorAll("#ul>li");
    var str = "hello word";
    var arr = [2,4,5,9,3];
    var obj={
      name:"kiki",
      age:12
    }
    for(var key of arr){
        console.log(key)
    }
  • 对比循环
  • for循环
  • arr.forEach()
  • for of 局限:无法获得当前遍历的位置;是ES6的功能,不是所有浏览器,所有数组和类数组对象都支持
    for of和for循环一样的,可以遍历数组、类数组对象、字符串,但是不能遍历对象和关联数组

    1. for in 只能遍历关联数组和对象,in其实不仅遍历当前对象自己的成员,且会延着原型链向父对象继续查找所有可用的成员名
  • for循环、for of、forEach三种遍历,哪种效率高?
    答:一样高。其实只有一种遍历,就是for循环。其他的都是封装的for循环而已。所以,ES5的其他遍历函数 indexOf、every、some、forEach、 map、filter 和 reduce,都没有效率的提升,因为内部都是for循环而已,只是语法简单而已

  • 是不是有了ES6,就不用ES5了?
    答:要看浏览器是否兼容ES6。如果使用框架和微信开发,基本上可以使用最新的语法。因为框架中和微信开发中都自带翻译工具(Babel),在项目打包时,会将ES6代码翻译成ES5代码,保证浏览器兼容性。如果没使用框架,使用原生或jquery开发,则尽量不要使用ES6

参数增强

  • 参数默认值
  • 什么是参数默认值(default)?
    ES6允许为函数定义中形参列表的最后一个参数定义默认值,如果没有传递实参,则自动调用形参的默认值
    function fn(a,b,c=0){...}
  • 使用
    定义:function 函数名(形参1,形参2,...,形参n=默认值)
    提示:如果调用函数时,没有提供最后一个实参,就自动用默认值代替
    html
    //形参默认值
    function add(a,b,c=10){
    console.log(a+b+c)
    }
    add(1,2,3)//6
    add(1,2)//13

    调用函数时,如果没有传入最后一个实参值,则自动使用默认值代替

兼容性写法:

function add(a,b,c){
      //兼容性写法
      c=c||10
      //或者写  c === undefined && (c=10)
      console.log(a+b+c)
    }
    add(1,2,3)//6
    add(1,2)//13

案例

//点餐案例
    function order(zhushi,xiaochi,yinliao="可乐"){
      console.log(`您点的套餐为:
        主食:${zhushi}
        小吃:${xiaochi}
        饮料:${yinliao}
      `)
    }
    order("米饭","鸡腿")
  • 剩余参数
    专门代替arguments的语法,代替arguments处理不确定参数个数的情况

  1. 定义函数时
    从头到尾获得所有实参值
    function fun(...数组名){...}
    提示:...的意思是”收集”,把传给函数的所有实参值都收集到...后的数组中保存
//剩余参数
    var arr=[]
    function order(...arr){
      console.log(arr)
    }
    order("套餐1","套餐2","套餐3")

剩余参数可以只收集部分实参值
function 函数名(形参1,形参2,...数组名){...}
提示:...数组名 收集的是除了之前形参1和形参2对应的实参值之外的所有剩余的实参值
注意:保存剩余实参值的结构是一个纯正的数组,可用数组家全部APi

var arr=[]
    function order(taocan1,taocan2,...arr){
      arr.forEach(function(elem,i){
        console.log(elem+i)//元素值+下标
      })
    }
    order("套餐1","套餐2","套餐3","套餐4")//套餐32套餐43

案例1:使用剩余参数语法求和

var arr=[];
    function add(...arr){
      console.log(arr)
      var result = arr.reduce(function(prev,elem,i,arr){
        return elem+prev;//prev是前一个参数,elem是当前参数值
      })
      return result;
    }
    console.log(add(1,2,3,4))//10

案例2:计算员工薪资,包含姓名和基本工资(bonus),以及其他来源工资(送外卖,跑滴滴,兼职...),使用剩余参数来实现

var arr=[];
    function add(name,jibengongzi,...arr){
      var result = arr.reduce(function(prev,elem){
        return prev+elem
      })
      var sum=result+jibengongzi
      // return sum;
      console.log(`${name}的总工资是${sum}`)
      // return `${name}的总工资是${sum}`
    }
    // console.log(add("lili",2000,1,2,3,4))
    add("lili",2000,1,2,3,4)
//用for循环做
var arr=[];
    function add(name,jibengongzi,...arr){
      // var result = arr.reduce(function(prev,elem){
      //   return prev+elem
      // })
      // var sum=result+jibengongzi

      // //用for循环做
      for(var i=0;i<arr.length;i++){
        var result=result+arr[i]
      }
      var sum = result+jibengongzi;
      // return sum;
      console.log(`${name}的总工资是${sum}`)
      // return `${name}的总工资是${sum}`
    }
    // console.log(add("lili",2000,1,2,3,4))
    add("lili",2000,1,2,3,4)
    add("bibi",3000,1,2,3,4,5)
  • 打散数组
    什么是打散数组?

    将一个数组打散为多个元素值,依次传给函数的多个形参变量,代替apply

    为什么使用打散数组?

    apply()也能打散数组参数,再传给要调用的函数。但是,apply()的本职工作是修改this,然后顺便帮忙打散数组。如果今后我们只想单纯的打散数组,跟this无关时。apply()就不好用了。如果用apply()单纯打散数组,必须给定一个无意义的对象作为第一个参数
    Math.max.apply( ? ,arr)

    var arr=[4,6,2]
    console.log(Math.max.apply(null,arr))//(this指针的方向,数组)

什么时候使用打散数组?

当一个函数不支持数组参数,而给定的实参值却是放在一个数组中的时候,都要先打散数组,再使用多个值
Math.max(...arr)

...先将数组打散为单个值,再传入前边的函数。好处是,...和this无关,只是专门单纯的打散数组

使用打散数组
(要考)
函数名(...数组)

复制数组:
第一种:var arr1 = arr.slice();
第二种: var arr1=[...arr]

合并两个数组
第一种: var arr3=[].concat(arr1,arr2)
第二种: var arr3=[...arr1,...arr3]

浅克隆一个对象
var obj1 = {...obj}

合并两个对象
第一种: var obj3 = Object.assign({},obj1,obj2)
将obj1和obj2打散后,所有的属性,都放入第一个参数空对象中返回
Object.assign方法用于对象的合并,第一个参数是目标对象,后面的参数都是源对象

第二种: var obj3={...obj1,...obj2}
笔试题:

  1. ...不是打散的意思吗?这里怎么成了收集?

    定义函数时,形参列表中的...是收集不确定个数的实参值的意思。调用函数时,实参值列表中的...是打散数组实参为多个实参值,分别传入的意思

  2. ...作为打散数组放在实参列表中时,不一定放在结尾?

    是的,可以和其他单独的实参值混搭

标签

评论

this is is footer