ES6特性

98 阅读5分钟

常量:const

作用:防止数据污染,不能被二次赋值

语法:const 名字 = 值

复杂数据:数据本身可以修改

应用场景

1.数据不想被修改

2.服务器拿到的数据:防止修改

形参默认值

作用: 在定义函数的时候:给形参赋值,这个值就叫做默认值

实例

默认打印99乘法表

  function chengFa(level = 9) {
    let str = ''
    for (let i = 1; i <= level; i++) {
    for (let j = 1; j <= i; j++) {
          str += `${i} * ${j} = ${i * j} &nbsp;`
        }
        str += '<br>'     }
document.body.innerHTML += str
   }

传入参数5:打印55乘法表5乘法表

chengFa(5)

没有参数:打印99乘法表

chengFa()

总结:参数一旦有了默认值:调用的时候如果不传,那么默认值生效;如果传了,实参生效,默认值不生效

解构

解构(解除解构:把复杂的东西简单化)

数组解构

数组解构:按顺序获取元素(与变量名字无关)

语法:let [变量1, 变量2...] = 数组

实例:

let arr = ['apple', 'banana', 'pitch', 'orange', 'watermelon', 'lichi']
​
let [, , , o, w] = 
​
console.log(o, w)

输出结果

orange watermelon

对象解构

对象解构:按属性名获取数据

语法:let { 属性名1, 属性名2...} = 对象

实例:

 let obj = { username: 'xiaomage', password: 'admin123', hobby: ['台球', '钓鱼', '打牌', '抽烟'] }
​
 const { hobby, username } = obj
​
 console.log(hobby, username)

输出结果:

['台球', '钓鱼', '打牌', '抽烟']  xiaomage

扩展:

let a = 1
let b = 2;
  // 要求:交换两个变量的值,不允许使用第三方变量
   [a, b] = [b, a]
   console.log(a, b)

结果为

2 1

剩余运算

作用:获取剩余的内容(不确定数量实参的时候)

常用场景:接收多余的实参

实例:

    function max(first, ...others) {
      // 第一个实参:给first
      // 第二个开始:剩下的都给others,others是一个数组
      // console.log(first, others)
      let m = first || -Infinity
      //Infinity 属性用于存放表示正无穷大的数值。
      // 其他的数据是否有比first更大的
      // console.log(m)
      others.forEach(function (item) {
        // 比较
        m = item > m ? item : m
      })
      console.log(m)
    }
    max()
    max(1, 2, 3)

输出结果:

-Infinity
3

扩展:解构中可以使用剩余运算(拆分对象:使用很少)

    let obj = { username: 'xiaomage', password: 'admin123', hobby: ['台球', '钓鱼', '打牌', '抽烟'] }
    const { hobby, ...others } = obj
    console.log(hobby, others)
    // 放到对象中使用剩余运算:得到的结果是对象

输出结果:

['台球', '钓鱼', '打牌', '抽烟'] password: "admin123"username: "xiaomage"

剩余运算又叫做拓展运算:可以打散数据,将复杂的数据变得简单

let arr = [1, 3, 2, 9, 5, 4, 8, 6, 7]

求数组中最大值

 max(arr)   // 输出[1, 3, 2, 9, 5, 4, 8, 6, 7]// 打散数组,变成单个的参数max(...arr)         // === max(1, 3, 2, 9, 5, 4, 8, 6, 7)  输出

总结

1.剩余:接收多个数据,一般用于形参:...形参变量

2.拓展:展开一个数据变成多个,一般用于实参(数组):...数组实参

3.局限一点: ...无外乎做两件事件:将多个数据变成数组,要么将数组变成多个数据

箭头函数

作用:简化函数的书写

语法:() => {}

  1. 参数只有1个:省略()

  2. 代码只有1行:省略{}

    自带return

    如果有return:一定有{}

this与函数的调用关系

this与函数调用关系:谁调用,this指向谁

  1. 函数调用模式:所有的函数调用,如果前面没有对象:此时都是window在调用:this一定指向window对象

    function fn1() {       // window.fn1 = function(){}
      console.log(this)
             }
       fn1()        // 本质:window.fn1()
    
  2. 方法调用模式:函数放到对象内部,是属性值

     const obj = {
          say: function () {
           console.log(this, this === obj)   // 对象内部的this一般都指向对象自己
          }
       }
        obj.say()
    
  3. 构造函数模式:new 构造函数()产生孩子对象(暂时不做要求)

     function Student() {     // 妈妈的肚子
          console.log(this)
        }
        // Student()        // this指向window(当普通函数使用的)
        const s = new Student()   // 出生一个孩子
        console.log(s)
    
  4. 事件函数

    <script>
     let box = document.querySelector('.box')
     // 事件回调函数的内部的this:指向事件源
      box.addEventListener('click', function () {
            console.log(this)       // this指向box元素
            // 不管是DOM0(on事件)还是DOM2(add事件),事件回调函数的内部的this都是指向事件源
        })
        box.addEventListener('click', () => {
            console.log(this)       // 箭头函数:不产生this(找到外面:window对象)
            // 想要有this必须有function关键字
        })
    </script>
    
  5. 借调模式

    借调模式:别人有的东西,借过来用:借调的主体就是使用的上下文环境

    上下文:代码所处的环境

    借调1:被借调函数的主体发生了改变(调用者发生改变)

    借调2:条件,为什么要借调? 别人的函数已经做好了某个功能,我当前需要用到那个功能,但是我又不想再写代码:可以借用

   // 借腹生子
    const richWoman = {
      name: '富婆',
     makeChild: function () {
       // this代表richWoman
        console.log(this.name + '重金求子')
     }
    }
    richWoman.makeChild()
    // 没钱:想生孩子,
    const ds = {
      name: '屌丝'
    }
      // 想借用richWoman.makeChild功能:借用要改变主体
      // 1. call借调:目标函数.call(新对象),借一次
      // 新对象:修改目标函数里面的this,修改函数的归属权
        richWoman.makeChild.call(ds)
      // 借调的目的:节省代码,提升开发效率
      // 目的很明确:但是现实很骨感:想要使用借调开发,前提是对别人的函数内部的代码要了如指掌

其他方式:

// 定义一个函数实现求和功能
   let obj = {
      add: function (a, b) {
       console.log(this, a + b)
      }
   }

假设这个功能很复杂,别的地方要使用需要借调

借调有三种方式

  1. call:一次性借调,借调后立即执行,目标函数.call(对象,对函数的传参,按顺序

    obj.add.call(null, 1, 2)     // null是不会修改this的,this指向window对象
    
  2. apply:一次性借调,跟call一样:传参的方式,必须传入数组(方便调用者选择)

    obj.add.apply({}, [1, 2])
    
     // 为什么要设计两个?方便调用者
    ​
        let a = 1
        let b = 2
    ​
        obj.add.call({}, a, b)
        let c = [1, 2]
        // call使用
        obj.add.call({}, c[0], c[1])       // 麻烦
        obj.add.apply({}, c)
        // 其实:记住一个就可以,call
        obj.add.call({}, ...c)
        // call和apply只有传参的区别:其他一模一样
    
  3. bind:永久性借调,借过来之后,可以重复用

    目标函数.bind(对象,顺序传参)

    bind返回一个结果:被借调后(修改了this之后)的函数副本

    let res = obj.add.bind({}, 3, 4) 
    console.log(res)
    res()
    res()
    // bind一次性调用
    obj.add.bind({}, 10, 20)()
    // bind大家会见到:用来改名(Vue会用到)
    let f = obj.add.bind({})
    console.log(f)
    f(1, 2)
    f(2, 3)

总结

  1. 借调是好东西,但是不会没有关系(不影响开发 ,影响效率)

  2. 长期学习的过程:需要掌握系统的API的源代码(自己也能定义函数实现)

  3. 借调有三种方式:call \ apply \ bind

call和apply是一样的:一次性借调,传参有点区别

bind:永久性借调,传参与call一样