ES6语法 --- 常用

80 阅读8分钟

ECMAScript 6.0是 JavaScript 语言的下一代标准,已经在 2015 年 6 月正式发布了。它的目标,是使得 JavaScript 语言可以用来编写复杂的大型应用程序,成为企业级开发语言。

let 和 const命令

let

  • 声明一个变量, 变量遵循块级作用域(其实就是变量被限制在了一个花括号内)

    {
      let a = 10;
      var b = 1;
    }
    
    a // ReferenceError: a is not defined.
    b // 1
    
  • 声明的变量可以被更改

    let a = 10
    a = 20
    
  • 声明的变量可以不给初始值

  • 没有变量提升

    / var 的情况
    console.log(foo); // 输出undefined
    var foo = 2;
    
    // let 的情况
    console.log(bar); // 报错ReferenceError
    let bar = 2;
    

const

  • 声明一个常量,遵循块级作用域
  • 声明的变量不可以更改
  • 声明的变量不可以不给初始值
  • 没有变量提升

除最后一条外,都是两者的区别

let/const 和 var 的区别

var

  • 定义的变量遵循全局作用域/函数作用域
  • 声明变量有提升(只提升定义,不提升赋值,变量是undefined)
  • 变量可以重复声明

let/const

  • 定义的变量/常量遵循块级作用域
  • 声明的变量/常量不能变量提升 具有暂时性死区(其实就是说没有变量提升)
  • 变量不可以重复声明

推荐大量的 const 结合少量的 let

箭头函数

ES6 新增的一个对以前普通函数的一个写法优化

  • 箭头函数专属的写法优化
    • 箭头函数的参数如果只有一个,并且没有默认值的时候,可以省略形参的小括号不写
    • 如果函数的形参有多个或者一个形参有默认值,或者没有形参,那么小括号必须写
    • 如果函数调用要执行的代码只有一行,那么可以省略大括号,并且默认自带return
  • 箭头函数和普通函数的区别
    • 写法不同
    • 函数内部的this不同
        // 1. 函数只有一个形参
        const fn1 = a => { }
        // 2. 函数只有一个形参 但是具有默认值
        const fn2 = (a = 100) => { }
        // 3. 函数没有形参
        const fn3 = () => { }
        // 4. 函数有多个形参
        const fn4 = (a, b, c, d) => { }

        // 5. 函数没有返回值, 并且内部代码有多行
        const fn5 = () => {
            console.log(1)
            console.log(1)
            console.log(1)
        }
        // 6. 函数不需要返回值, 但是内部代码有多行
        const fn6 = () => console.log(1)
        // 7. 当函数只需要返回一个对象的时候
        // const fn7 = () => {
        //     return { a: 1, b: 2 }
        // }
        const fn7 = () => ({ a: 1, b: 2 })
        // console.log(fn7())

        // 8. 函数内部只需要返回一个数组
        const fn8 = () => [1, 2, 3]
        // console.log(fn8())

        // 9. 函数内部返回一个新的箭头函数
        // const fn9 = () => {
        //     // return function () {}
        //     return () => {}
        // }
        const fn9 = () => () => {}
        console.log(fn9())

解构赋值

快速的从数组或对象中 拿到 数据

数组的解构赋值

        // 数组的解构赋值
        let arr = [1,2,3]

        // let [a,b,c] = arr
        // console.log(a);      // 1
        // console.log(b);      // 2
        // console.log(c);      // 3

        // let [a,b] = arr
        // console.log(a);     // 1
        // console.log(b);     // 2

        // let [a, ,b] = arr
        // console.log(a);     // 1
        // console.log(b);     // 3

对象的解构赋值

        // 对象的解构赋值
        let obj = {
            name: '张三',
            age: 23,
            sex: '男'
        }
        
        // 新定义的变量必须是对象内的某个键
        // let {name,age,sex} = obj
        // console.log(name);       // 张三
        // console.log(age);        // 23
        // console.log(age);        // 男
        
        let {name,sex} = obj
        console.log(name);      // 张三
        console.log(sex);       // 男

对象的简写

  • 当对象的key和value完全一样的时候,并且value是个变量,可以省略一个不写
var name = 'XXX'
var obj = {
    name: name
}

var obj1 = {
    name
}
  • 当对象内key对应的value是个函数的时候,并且不是箭头函数,可以省略 function 关键字和冒号 不写
var obj = {
    fn: function () {
        console.log(123)
    },
    fn1() {
        console.log(456)
    }
}

展开运算符

  • 语法:...
  • 在数组前写上展开运算符,可以将数组内的数据展开并在一行显示
        // 展开运算符   ...

        let arr = [1,2,3,4,5]
        let arr2 = [6,6,6]
        // console.log(...arr);                     // 1  2 3 4 5
        // console.log(...arr2);                    // 6 6 6
        // console.log(...[1,2,3,4,5,...arr2]);     // 1 2 3 4 5 6 6 6
  • 在函数的形参前写上 ...,能够将所有实参的内容,存放在这个形参中,并且是以数组的形式
  • 如果一个参数都没有传递,那这个形参就是个空数组
  • 注意: 如果一个形参前书写了...那么这个形参后面就不要写形参了

函数的this指向

  • 普通函数内部的 this 指向和函数的书写没有任何关系,而是和函数的调用有关系
  • 箭头函数内部没有 this, 他的 this 是从你定义的哪一行开始,向上一直寻找, 直到找到一个 this
        // 普通函数的this 指向
        // function fn() {
        //     console.log(this);
        // }
        // 1. 在代码中直接调用函数  this === window
        // fn()         window

        // 2. 放在一个对象中调用        this === 当前对象
        // let obj = {
        //         name: '我是obj对象的名字',
        //         age: 10086,
        //         objFn: fn
        // }
        // obj.objFn()          // obj{}

        // 3. 将上述的函数 放在 定时器或者倒计时器内部  this === window
        // window.setTimeout(fn, 10)

        // 4. 将上述函数 放在事件处理中             this === 事件源
        // let div = document.querySelector('div')
        // div.onclick = fn

        // 5. 将函数放在自执行函数中  目前市场已经不多见  this === window
        // (fn)()

        const fn1 = () => {
            console.log(this)
        }
        function fn2() {
            fn1()
        }
        function fn3() {
            const f = () => {
                console.log(this)
            }
            f()
        }

        var obj = {
            objFn1: fn1,
            objFn2: fn2,
            objFn3: fn3
        }
        // obj.objFn1()    // window
        // obj.objFn2()    // window
        // obj.objFn3()    // obj

修改函数this 指向

        // 修改this指向的方法
        function fn1 (a,b,c) {
            console.log(a,b,c,this);
        }

        let obj = {
            name: '张三'
        }

        // fn1(1,2,3)

        
        // fn1.call(obj,1,2,3)                      //先指向,后参数,立即执行
        // fn1.apply(obj,[11,22,33])                //先指向,后参数(必须数组类型),立即执行
        let res = fn1.bind(obj,111,222,333)         //先指向,后参数,不立即执行,将修改好的this的函数返回
        res()

Set和Map数据结构

  • ES6 新增的两种数据结构
  • 共同点: 都不接受重复数据

Set数据结构

  • 类似于数组的数据结构

  • 按照索引排列的数据结构

  • 创建 Set 数据结构

    • 语法: var s = new Set([数据1, 数据2, 数据2, 数据3, ... ])
  • Set 数据结构的属性和方法

    1. size 属性

      • 语法: 数据结构.size
      • 返回值: 该数据结构内有多少个数据
    2. add() 方法

      • 语法: 数据结构.add(数据)

        • 作用: 向该数据结构内添加数据
    3. has() 方法

      • 语法: 数据结构.has(数据)
      • 返回值: true---表示数据结构内有该数据; false---表示数据结构内没有该数据
    4. delete() 方法

      • 语法: 数据结构.delete(数据)
      • 作用: 删除该数据结构内的某一个数据
    5. clear() 方法

      • 语法: 数据结构.clear()
      • 作用: 清除该数据结构内所有数据
    6. forEach() 方法

      • 语法: 数据结构.forEach(function (value, key, origin) {})

Map 数据结构

  • 类似于对象的数据结构, 但是他的 key 可以是任何数据类型

  • 可以被叫做一个 值=值 的数据结构

  • 创建一个 Map 数据结构

    • 语法: var m = new Map([ [key, value], [key, value] ])
  • Map 数据结构的属性和方法

    1. size 属性

      • 语法: 数据结构.size
      • 得到: 该数据内有多少个数据
    2. set() 方法

      • 语法: 数据结构.set(key, value)
      • 作用: 想该数据内添加数据
    3. get() 方法

      • 语法: 数据结构.get(key)
      • 作用: 数据结构内该 key 对应的 value
    4. has() 方法

      • 语法: 数据结构.has(key)
      • 返回值: true---数据结构内有该数据; false---数据结构内没有该数据
    5. delete() 方法

      • 语法: 数据结构.delete(key)
      • 作用: 删除该数据结构内的某一个数据
    6. clear() 方法

      • 语法: 数据结构.clear()
      • 作用: 清除该数据结构内所有数据
    7. forEach() 方法

      • 语法: 数据结构.forEach(function (value, key, origin) {})

模块化开发(重点)

  • 就是把我们的完整功能, 拆开成为一个一个的独立功能(模块)

    • 一个 JS 文件就是一个独立模块
  • 根据业务需求, 来进行模块整合

  • 当模块化开发的时候

    • 我们需要把多个逻辑书写在多个 JS 文件内
    • 此时, 每一个文件都是独立的文件, 都是一个独立的模块作用域(文件作用域)
    • 该文件内, 只能使用自己文件内的变量, 不能使用其他文件内的变量
  • 导出/导入

    • 导出: 在一个文件内向外暴露一些内容
    • 导入: 导入该文件的同时, 拿到它向外暴露的内容
  • 浏览器使用 ES6 模块化语法的要求

    • script 标签必须要有一个 type=module 的属性
    • 页面必须要在服务器上打开(可以借助 live server)
  • 导出语法

    • 语法1: export default 你要导出的数据

      • 一个文件只能导出一个 default 数据
      const num = 100
      const fn = () => {
          console.log('我是 header.js')
      }
      const obj = {
          num: num,
          fn: fn
      }
      export default obj
      
    • 语法2: export 定义变量 = 值

      • 一个文件可以导出多个新定义的变量
      export const s = 100
      export let a = 200
      
  • 导入语法

    • import 变量 from '文件'

      • 这个语法必须对应导出语法1
      import myObj from './index.js'
      
    • import { 导出的内容 } from '文件'

      • 这个语法必须对应导出语法2
      import {s, a} from './index.js'