ES6--ES11


ES6--ES11

  • ES6
  • 1. let 关键字
    • 1.1 声明变量
    • 1.2 块级作用域
    • 1.3 不存在变量提升
    • 1.4 不影响作用域链
    • 1.5 案例实践 -- 点击 DIV 换色
  • 2. const 关键字
    • 2.1 声明常量
    • 2.2 不允许重复声明
    • 2.3 值不允许修改
    • 2.4 块儿级作用域
    • 2.5 对于数组和对象的元素修改, 不算做对常量的修改
  • 3. 变量的解构赋值
    • 3.1 数组的结构
    • 3.2 对象的解构
  • 4. 模板字符串
    • 4.1 模板字符串声明
    • 4.2 字符串中可以出现换行符
    • 4.3 可以使用 ${xxx} 形式输出变量
  • 5. 简化对象写法
  • 6. 箭头函数
    • 6.1 箭头函数 this 指向声明时所在作用域下 this 的值
    • 6.2 箭头函数不能作为构造实例化对象
      • 6.2.1 函数this指向
    • 6.3 不能使用 arguments 变量
    • 6.4 箭头函数的简写
      • 6.4.1 如果形参只有一个,则小括号可以省略
      • 6.4.2 函数体如果只有一条语句,则花括号可以省略
    • 6.5 箭头函数实践
      • 6.5.1 点击 div 2s 后颜色变成『粉色』
    • 6.6 箭头函数小结
  • 7. 函数参数默认值
    • 7.1 形参初始值
    • 7.2 与解构赋值结合
  • 8. rest 参数
    • 8.1 rest 参数必须要放到参数最后
  • 9. spread 扩展运算符
    • 9.1 数组的合并
    • 9.2 数组的克隆
    • 9.3 将伪数组转为真正的数组
  • 10. Symbol
    • 10.1 创建Symbol
    • 10.2 不能与其他数据进行运算
    • 10.3 Symbol 创建对象属性
    • 10.4 Symbol 内置值


ES6

1. let 关键字

let 关键字用来声明变量,使用 let 声明的变量有几个特点:

  1. 不允许重复声明
  2. 块儿级作用域
  3. 不存在变量提升
  4. 不影响作用域链

1.1 声明变量

      // 可以使用let声明单个变量
      let a;
      // 可以在声明变量的同时赋值
      let b = 100;
      // 可以一次同时声明多个变量
      let c,d,e;
      // 可以声明多个变量同时赋值
      let f = 'abc', g = 123, h = {}, i = [];
      // 变量不能重复声明
      // let a = 100;

在这里插入图片描述

var 可以重复声明变量:

      var j = 100;
      var j = [];
      console.log(j)

在这里插入图片描述

1.2 块级作用域

      {
        let age = 12;
      }
      console.log(age)

在这里插入图片描述

var 不具有块级作用域

      {
        var username = 'zs'
      }
      console.log(username)

在这里插入图片描述

1.3 不存在变量提升

var 声明变量,相当于在最前面声明一个变量。

      console.log(myage)
      var myage = 20

上面代码相当于:

	  var myage
      console.log(myage)
      myage = 20

由于声明了没有赋值,所以输出为undefined

在这里插入图片描述

而 let 声明变量不会存在变量提升,会直接报错

      console.log(myage)
      let myage = 20

在这里插入图片描述

1.4 不影响作用域链

      {
        let myname = '张三'
        {
          // 在该作用域下没有 myname,会向上一级作用域寻找 myname
          // 找到输出
          console.log(myname)
          // 没有找到报错
          console.log(myage)
        }
      }

在这里插入图片描述

1.5 案例实践 – 点击 DIV 换色

使用 var 声明变量 i ,并且使用 items[i] 修改样式会报错

DOCTYPE html>
<html lang="en">
  <head>
    <meta charset="UTF-8" />
    <meta http-equiv="X-UA-Compatible" content="IE=edge" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Documenttitle>
    <style>
      .item {
        width: 100px;
        height: 50px;
        border: solid 1px rgb(42, 156, 156);
        float: left;
        margin-right: 10px;
      }
    style>
  head>
  <body>
    <div>
      <div class="item">div>
      <div class="item">div>
      <div class="item">div>
    div>
    <script>
      // 获取元素
      let items = document.querySelectorAll('.item')
      // console.log(items)
      // 给元素绑定事件
      for( var i=0; i<items.length; i++ ) {
        items[i].onclick = function() {
          //修改当前元素的背景颜色
          // 使用 items[i] 进行修改
          items[i].style.background = 'pink'
        }
      }
    script>
  body>
html>

ES6--ES11_第1张图片

原因使用 var 声明 i 相当于在全局声明了一个变量 i 每次 i++,相当于对全局的 i ++,事件绑定完成后 i 为3,当点击元素触发事件会导致数组下标越界。

使用 let 则不会,因为 let 存在块级作用域

      // 获取元素
      let items = document.querySelectorAll('.item')
      // console.log(items)
      // 给元素绑定事件
      for( let i=0; i<items.length; i++ ) {
        items[i].onclick = function() {
          //修改当前元素的背景颜色
          // 使用 items[i] 进行修改
          items[i].style.background = 'pink'
        }
      }

ES6--ES11_第2张图片

2. const 关键字

const 关键字用来声明常量,const 声明有以下特点

  1. 声明必须赋初始值
  2. 标识符一般为大写
  3. 不允许重复声明
  4. 值不允许修改
  5. 块儿级作用域

2.1 声明常量

    // 声明常量
    // 声明必须赋初始值
    // 标识符一般为大写(潜规则), 不大写也不报错, 只是常量习惯性大写
    const PI = 3.14
    console.log(3.14)

在这里插入图片描述

声明常量不赋初始值会报错

    const A

在这里插入图片描述

2.2 不允许重复声明

    const PI = 3.14
    const PI = 3.1415

在这里插入图片描述

2.3 值不允许修改

    const PI = 3.14
    PI = 3.1415

在这里插入图片描述

2.4 块儿级作用域

    const PI = 3.14
    {
      // 在该作用域下没有声明PI, 会向上一级作用域寻找
      console.log(PI)
    }

在这里插入图片描述

2.5 对于数组和对象的元素修改, 不算做对常量的修改

数组和对象变量中保存的为数组和对象的地址,改变对象和数组中的元素没有修改其地址,所以相当于没有修改数组和对象变量,不会报错

    const ARR = ['a', 1, 2, 3, 45]
    ARR[0] = 0
    console.log(ARR)

ES6--ES11_第3张图片

声明对象类型使用 const,非对象类型声明选择 let

3. 变量的解构赋值

ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构赋值。

3.1 数组的结构

    const arr = ['apple', 'banner', 'orange']
    // 相当于声明了三个变量 fruit1, fruit2, fruit3 
    // 将数组 arr 中的值按下标顺序赋值给三个变量
    // 数组的解构使用 []
    let [fruit1, fruit2, fruit3] = arr
    console.log(fruit1)
    console.log(fruit2)
    console.log(fruit3)

在这里插入图片描述

3.2 对象的解构

    const person = {
      name: 'zs',
      age: 13,
      sayHello: function() {
        console.log('Hello!')
      }
    }
    // 对象的解构是按照对象中的属性名将属性值赋值给相同名对应的变量
    let {name, age, sayHello} = person
    console.log(name)
    console.log(age)
    sayHello()
    // 对象解构赋值的用处
    // person.sayHello() 麻烦
    // 解构出来,直接调用,不用每次写对象名
    sayHello()

在这里插入图片描述

    // 对象解构可以单独解构出其中的属性
    let {sayHello} = person
    sayHello()

在这里插入图片描述

频繁使用对象方法、数组元素,就可以使用解构赋值形式

4. 模板字符串

模板字符串(template string)是增强版的字符串,用反引号( ` )(键盘esc键下面)标识,特点:

  1. 字符串中可以出现换行符
  2. 可以使用 ${xxx} 形式输出变量

4.1 模板字符串声明

    let str = `声明了一个模板字符串`
    console.log(str)

在这里插入图片描述

4.2 字符串中可以出现换行符

    let str = `
      
`
console.log(str)

ES6--ES11_第4张图片

4.3 可以使用 ${xxx} 形式输出变量

    let name = 'zs'
    let age = 13
    let str = `我的名字是${name}, 我的年龄为${age}`
    console.log(str)

在这里插入图片描述

当遇到字符串与变量拼接的情况使用模板字符串

5. 简化对象写法

ES6 允许在大括号里面,直接写入变量和函数,作为对象的属性和方法。这样的书写更加简洁。

    let name = 'zs'
    let age = 12
    let sayHello = function() {
      console.log('你好!')
    }
    let person1 = {
      name,
      age,
      sayHello,
      sayHello2() {
        console.log('hello!')
      }
    }
    // 相当于
    // let person2 = {
    //   name: name,
    //   age: age,
    //   sayHello: sayHello,
    //   sayHello2: function() {
    //     console.log('hello!')
    //   }
    // }
    console.log(person1.name)
    console.log(person1.age)
    person1.sayHello()
    person1.sayHello2()

在这里插入图片描述

6. 箭头函数

ES6 允许使用箭头(=>)定义函数。

    // 定义一个普通的函数
    let f1 = function() {
      console.log('hello')
    }
    // 定义箭头函数
    let f2 = () => {
      console.log('world')
    }

    f1()
    f2()

在这里插入图片描述

6.1 箭头函数 this 指向声明时所在作用域下 this 的值

箭头函数的 this 是静态的. this 始终指向函数声明时所在作用域下的 this 的值

      function getThis1() {
        console.log(this)
      }
      let getThis2 = () => {
        console.log(this)
      }
      // 直接调用
      getThis1()
      getThis2()

在这里插入图片描述

      function getThis1() {
        console.log(this.name)
      }
      let getThis2 = () => {
        console.log(this.name)
      }
      window.name = 'window'
      const NAME = {
        name: 'NEW_NAME'
      }
      // 使用call方法改变this指向
      getThis1.call(NAME)
      getThis2.call(NAME)

箭头函数的this指向并没有发生更改,依旧指向声明时候作用域下的this(window)
在这里插入图片描述

6.2 箭头函数不能作为构造实例化对象

      let Person = (name, age) => {
        this.name = name
        this.age = age
      }
      let p = new Person('zs', 12)
      console.log(p)

在这里插入图片描述

6.2.1 函数this指向

函数this的指向在函数定义的时候是不能确定的,在调用执行函数时才能明确函数this的指向。

  1. 函数名() 调用函数,this指向window
  2. 对象名.函数()this指向调用这个函数的对象
  3. 函数作为事件处理函数时,this指向触发事件的元素
  4. 构造函数中的this指向new出来的对象
  5. 定时器函数中的this指向window

6.3 不能使用 arguments 变量

      // 普通函数可以使用 arguments 变量获取传入的参数值
      let fn1 = function() {
        console.log(arguments)
      }
      // 箭头函数不能使用 arguments 变量获取传入的参数值
      let fn2 = () => {
        console.log(arguments)
      }
      fn1(1,2,3)
      fn2(1,2,3)

ES6--ES11_第5张图片

6.4 箭头函数的简写

6.4.1 如果形参只有一个,则小括号可以省略

      let fn3 = n => {
        console.log(n)
      }
      fn3(100)

在这里插入图片描述

6.4.2 函数体如果只有一条语句,则花括号可以省略

函数体如果只有一条语句,则花括号可以省略,函数的返回值为该条语句的
执行结果

      let fn4 = n => console.log(n)
      fn4(100)
      let fn5 = n => n*n
      // 相当于:
      // let fn5 = n => {
      //   return n*n
      // }
      let res = fn5(100)
      console.log(res)

在这里插入图片描述

6.5 箭头函数实践

6.5.1 点击 div 2s 后颜色变成『粉色』

普通函数实现:

      // 获取元素
      let div = document.querySelector('div')
      // 绑定事件
      div.addEventListener( 'click', function() {
        // 回调函数使用普通函数
        // 由于定时器函数的this指向window
        // 需要保存this,事件处理函数指向触发事件的元素
        let _this = this
        setTimeout( function() {
          _this.style.background = 'pink'
        }, 2000 )
      } )

ES6--ES11_第6张图片
ES6--ES11_第7张图片

箭头函数实现:

      // 获取元素
      let div = document.querySelector('div')
      // 绑定事件
      div.addEventListener('click', function () {
        // // 回调函数使用普通函数
        // // 由于定时器函数的this指向window
        // // 需要保存this,事件处理函数指向触发事件的元素
        // let _this = this
        // setTimeout(function () {
        //   _this.style.background = 'pink'
        // }, 2000)

        // 箭头函数实现
        // 由于箭头函数this指向定义函数作用域下的this,所以箭头函数this指向触发事件的元素
        setTimeout(() => {
          this.style.background = 'pink'
        }, 2000)
      })

ES6--ES11_第8张图片
ES6--ES11_第9张图片

6.6 箭头函数小结

  • 箭头函数适合与 this 无关的回调. 定时器, 数组的方法回调
  • 箭头函数不适合与 this 有关的回调. 事件回调, 对象的方法

7. 函数参数默认值

ES6 允许给函数参数赋值初始值

7.1 形参初始值

    // 具有默认值的参数, 一般位置要靠后
    let f1 = function( a, b, c=10 ) {
      console.log(a+b+c)
    }
    // 没有给有默认值的参数传值时,参数的值为默认值
    f1(1,2,3)
    f1(1,2)

    // 有默认值的参数放前面,当传入的参数个数不等于参数的总数时会出现错误
    // 一般位置要靠后
    let f2 = function( a, b=12, c ) {
      console.log(a+b+c)
    }
    // 1 会赋值给 a
    // 2 会赋值给 b
    // c 没有传入值,三个数相加会出现错误 NaN
    // c 为undefined
    f2(1,2)

在这里插入图片描述

7.2 与解构赋值结合

    function connect({host="127.0.0.1", username,password, port}){
        console.log(host)
        console.log(username)
        console.log(password)
        console.log(port)
    }
    connect({

        username: 'root',
        password: 'root',
        port: 3306
    })

对象中的值解构 出来赋值给对应的变量,username: ‘root’ 对应 username,… ,由于对象中没有属性 host ,所以 host 会使用默认值
在这里插入图片描述

8. rest 参数

ES6 引入 rest 参数,用于获取函数的实参,用来代替 arguments

      let f1 = function (...args) {
        // rest 参数 会将传入的多个参数转为一个数组
        // 转为数组后可以使用数组的方法 filter some every map ...
        console.log(args)
      }
      f1(1, 2, 3)
      // 箭头函数也可以使用 rest 参数
      let f2 = (...args) => {
        console.log(args)
      }
      f2(4, 5, 6)

ES6--ES11_第10张图片

8.1 rest 参数必须要放到参数最后

rest 参数相当于一个参数接收多个参数值转成一个数组,如果不放在最后那么相当于前的参数值都被rest 参数获取,后面的参数将不会有参数传入,所以rest 参数必须放在最后。

      let f3 = (a, ...args, b)=> {
        console.log(a)
        console.log(args)
        console.log(b)
      }
      f3(1,2,3,4,5,6,7)

在这里插入图片描述

rest 参数非常适合不定个数参数函数的场景

9. spread 扩展运算符

扩展运算符(spread)也是三个点(…)。它好比 rest 参数的逆运算,将一个数组转为用逗号分隔的参数序列,对数组进行解包。

    const arr = [1,2,3,4,5]
    console.log(arr)
    console.log(...arr)

ES6--ES11_第11张图片

9.1 数组的合并

先将两个或多个数组进行拓展然后再组合成一个数组

    const arr1 = [1,2,3,4,5]
    const arr2 = [6,7,8,9,10]
    const newArr = [...arr1, ...arr2]
    console.log(newArr)

ES6--ES11_第12张图片

9.2 数组的克隆

使用该方法进行数组的克隆为浅拷贝

    const arr1 = [1,2,3,4,5]
    const arr2 = [...arr1]
    console.log(arr2)

ES6--ES11_第13张图片

9.3 将伪数组转为真正的数组

    <div>div>
    <div>div>
    <div>div>
      const divs = document.querySelectorAll('div')
      console.log(divs)
      const divArr = [...divs]
      console.log(divArr) 

ES6--ES11_第14张图片

10. Symbol

ES6 引入了一种新的原始数据类型 Symbol,表示独一无二的值。它是JavaScript 语言的第七种数据类型,是一种类似于字符串的数据类型

Symbol 特点

  1. Symbol 的值是唯一的,用来解决命名冲突的问题
  2. Symbol 值不能与其他数据进行运算
  3. Symbol 定义的对象属性不能使用 for…in 循环遍历,但是可以使用Reflect.ownKeys 来获取对象的所有键名

10.1 创建Symbol

    let s1 = Symbol()
    console.log(s1, typeof s1)
    // 使用 Symbol() 创建的 Symbol 每次都不一样
    let s2 = Symbol('hello') // 'hello'只是一个对于 Symbol 的描述,类似对Symbol的注释
    let s3 = Symbol('hello')
    console.log(s2 === s3)
    // Symbol.for 创建
    // 第一次创建会直接创建一个新的 Symbol
    // 第二次创建会先查看是否已经传建了,已经有了则不在创建,没有就创建
    let s4 = Symbol.for('hello')
    let s5 = Symbol.for('hello')
    console.log(s4 === s5)

在这里插入图片描述
Symbol 显示的为Symbol(),可以把其理解为一个字符串,具有唯一性的字符串。

Symbol.for()与Symbol()的区别:都会生成新的Symbol,但是调用多次的Symbol()会生成多个不同的Symbol,调用多次的Symbol.for()只会生成一个Symbol。

10.2 不能与其他数据进行运算

      let result = s + 100
      let result = s > 100
      let result = s + s

在这里插入图片描述

10.3 Symbol 创建对象属性

      let game = {
        name: '俄罗斯方块',
        up: function () {},
        down: function () {},
      }

假设不知道该对象里面有什么属性和方法,向其中添加 up 和 down 方法,但是把确定其中是否有 up 和 down 方法,此时可以使用 Symbol
在这里插入图片描述

      // 声明一个对象
      let methods = {
          up: Symbol(),
          down: Symbol()
      };
      // 向对象中添加方法
      game[methods.up] = function(){
          console.log("我可以改变形状");
      }
      game[methods.down] = function(){
          console.log("我可以快速下降!!");
      }
      // 调用
      game[methods.up]()
      game[methods.down]()
      console.log(game);

ES6--ES11_第15张图片

      let youxi = {
        name: '狼人杀',
        [Symbol('say')]: function () {
          console.log('我可以发言')
        },
        [Symbol('zibao')]: function () {
          console.log('我可以自爆')
        },
      }
      console.log(youxi)

如上无法调用,每次Symbol(‘say’)的值都不一样
要使如上的方法能够进行调用,需要进行如下修改:

      // 先在外面声明 Symbol 变量
      let say = Symbol('say')
      let zibao = Symbol('zibao')
      let youxi = {
        name: '狼人杀',
        [say]: function () {
          console.log('我可以发言')
        },
        [zibao]: function () {
          console.log('我可以自爆')
        },
      }
      console.log(youxi)
      youxi[say]()
      youxi[zibao]()

ES6--ES11_第16张图片

10.4 Symbol 内置值

除了定义自己使用的 Symbol 值以外,ES6 还提供了 11 个内置的 Symbol 值,指向语言内部使用的方法。可以称这些方法为魔术方法,因为它们会在特定的场景下自动执行。

ES6--ES11_第17张图片
在这里插入图片描述
可以修改内置方法被自动调用时的执行效果

      class Person {
        static [Symbol.hasInstance](param) {
          console.log(param)
          console.log('我被用来检测类型了')
          return false
        }
      }

      let o = {}

      console.log(o instanceof Person)

在这里插入图片描述

      const arr = [1, 2, 3]
      const arr2 = [4, 5, 6]
      arr2[Symbol.isConcatSpreadable] = false
      console.log(arr.concat(arr2))

ES6--ES11_第18张图片

你可能感兴趣的:(前端学习,javascript,前端,html5,es6,ecmascript)