美文网首页
ES6(玺哥篇)

ES6(玺哥篇)

作者: cj_jax | 来源:发表于2019-01-03 11:57 被阅读0次

    ES6 - ECMAScript 6.0(ES2015)

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

    • ECMAScript 6 入门 阮一峰
    • ES6也叫ES2015,前者根据版本号来说明,后者按照发布年份来说明
      • ES7 -> ES2016
      • ES8 -> ES2017
      • ES9 -> ES2018
    • ECMAScript 标准每年都会发布一个新的版本
    • 注意
      • 1 平时所说的 ES6 就泛指所有新的语法规则
      • 2 使用这些新语法的时候,也不需要刻意分清是 ES6/ES7/ES8 的语法

    变量声明- let、const

    let

    • ES6 新增了 let 命令,用来声明变量。它的用法类似于 var,但是所声明的变量,只在 let 命令所在的代码块内有效。

    • let特点:

      • 1 块级作用域(ES6)
      • 2 先声明再使用
      • 3 不允许重复声明
    /* 基本使用 */
    let num = 2
    
    {
      let num = 9
    }
    console.log(num)
    

    const

    • const 声明一个只读的常量。一旦声明,常量的值就不能改变。
    • const 的作用域与 let 命令相同:只在声明所在的块级作用域内有效
    const PI = 3.1415
    console.log(PI) // 3.1415
    
    // 修改 常量的值 会报错
    PI = 3 // TypeError: Assignment to constant variable.
    
    // 可以修改对象中属性的值
    const user = { name: 'rose' }
    user.name = 'jack'
    

    字符串模板

    • 说明:代替原始的字符串拼接
    const num = 1
    
    // ${} 中可以使用JS表达式
    let dv = `<div>${num}</div>`
    // 相当于:
    let dv = `<div>` + num + '</div>'
    

    箭头函数

    • ES6 箭头函数
    • 注意 1:函数体内的 this 对象,就是定义时所在的对象(一般是外层函数中的 this)
    • 注意 2:无法使用 arguments,没有 arguments 对象
    • 注意 3:不能当作构造函数,不能使用 new 创建对象
    • 注意:不要在 Vue 的选项属性或回调上使用箭头函数
      • 比如:created: () => console.log(this.a)vm.$watch('a', newValue => this.myMethod())
    /* 语法: */
    var fn = arg => arg
    
    // 上面的箭头函数等同于:
    var fn = function(arg) {
      return arg
    }
    
    var fn = () => {
      console.log('随机内容')
    }
    // 等同于:
    var fn = function() {
      console.log('随机内容')
    }
    

    rest 参数

    • ES6 引入 rest 参数(形式为...变量名),用于获取函数的多余参数,这样就不需要使用 arguments 对象了
    • 说明:rest 参数的类型是:数组
    • 注意:rest 参数之后不能再有其他参数(即只能是最后一个参数),否则会报错
    function add(...values) {
      var sum = 0
      values.forEach(function(val) {
        sum += val
      })
      return sum
    }
    
    add(2, 5, 3) // 10
    
    
    // 报错
    function f(a, ...b, c) {
      // ...
    }
    

    解构赋值

    • ES6 解构
    • ES6 允许按照一定模式,从数组和对象中提取值,对变量进行赋值,这被称为解构(Destructuring)。
    // 对象解构
    const obj = { foo: 'aaa', bar: 'bbb' }
    var { foo, bar } = obj
    // var foo = obj.foo
    // var bar = obj.bar
    foo // "aaa"
    bar // "bbb"
    
    
    // 数组解构
    const arr = [1, 2, 3]
    var [a, b, c] = arr
    // var a = arr[0]
    // var b = arr[1]
    a // 1
    b // 2
    c // 3
    
    // 函数参数的解构赋值
    function foo({ x }) {
      console.log(x) // 1 2
    }
    
    foo({ x: 1, y: 2 })
    

    对象简化语法

    • 对象中的属性和方法,都可以使用简化语法
    /* 属性的简化语法: */
    var foo = 'bar'
    var baz = { foo }
    
    // 等同于
    var baz = { foo: foo }
    
    /* 方法的简化语法: */
    var o = {
      method() {
        return 'Hello!'
      }
    }
    // 等同于
    var o = {
      method: function() {
        return 'Hello!'
      }
    }
    

    属性名表达式

    • ES6 允许字面量定义对象时,用表达式作为对象的属性名,即把表达式放在方括号内。
    var propKey = 'foo'
    var methodKey = 'bar'
    
    var obj = {
      [propKey]: true,
      // foo: true
      ['a' + 'bc']: 123,
      // abc: 123
      [methodKey]() {
        return 'hi'
      }
    }
    

    class 关键字

    • ES6 以前,JS 是没有 class 概念的,而是通过构造函数+原型的方式来实现的
    • 注意:ES6 中的 class 仅仅是一个语法糖,并不是真正的类,与 Java 等服务端语言中的类是有区别的
    • ES6 - 文档
    class Person {
      constructor() {
        // 实例属性
        this.name = 'jack'
      }
    
      // 实例方法
      say() {}
    
      // 静态方法
      static coding() {}
    }
    // 静态属性
    Person.age = 0
    
    console.log(Person.age)
    
    • 类继承:
      • 1 如果子类提供了 constructor,那么,必须要调用super()
      • 2 子类添加属性,必须在 super() 调用后面
    // 类继承:
    class Chinese extends Person {
      constructor(name, gender, weight) {
        super(name, gender)
    
        this.weight = weight
      }
    }
    
    const ch = new Chinese('小明', '男', 130)
    

    静态属性和实例属性

    • 静态属性:直接通过类名访问
    • 实例属性:通过实例对象访问

    ES6 模块化 - import 和 export

    • 导入和导出

    • import:导入模块

    • export:导出模块

    • 注意 1:export default 每个模块只能使用一次

    • 注意 2:export 每个模块可以使用多次

    • 注意 3:一个模块可以导出多个内容,export defaultexport 可以一起使用

    // main.js
    // 导入 default 内容,可自定义导入名称
    // import num from './a.js'
    import num1 from './a.js'
    
    // a.js
    const num = 123
    export default num
    
    // main.js
    // 导入 export内容
    // 注意:导入非default模块内容(str、fn),必须与 导出名称 相同,或者通过 as 修改
    // 注意:必须使用花括号
    import { str, fn } from './b'
    
    // 加载并修改变量名
    // import { str as str1, fn } from './b'
    // 整体加载
    // import * as bModule from './b'
    
    // b.js
    export const str = 'abc'
    export function fn() {}
    
    // main.js
    import { str, fn } from './b'
    
    // b.js
    const str = 'abc'
    function fn() {}
    // 一次性导出
    export { str, fn }
    

    数组扩展运算符

    • 扩展运算符(spread)是三个点(...)。作用:将一个数组转为用逗号分隔的参数序列
    var arr = ['a', 'b', 'c']
    console.log(...arr)
    
    // 上面这句代码相当于:
    console.log(arr[0], arr[1], arr[2])
    

    对象扩展运算符

    • 注意:该语法不是真正的 ES 规范,需要使用stage-2解析
    var obj = { name: 'jack', age: 19 }
    var o = { ...obj, gender: 'male' }
    // o => {name: 'jack', age: 19, gender: 'male'}
    

    Promise 异步编程

    • Promise 是异步编程的一种解决方案,它允许你以一种同步的方式编写异步代码
    • promise:承诺、保证
    • ES6 - Promise

    回调地狱问题

    • JS 是通过回调函数来实现异步编程的,当异步操作多了以后,就会产生回调嵌套回调的问题,这就是回调地狱
    // 按序读取文件:a -> b -> c -> d
    
    readFileAsync('a.txt', (err, data) => {
      console.log('文件a: ', data)
      readFileAsync('b.txt', (err, data) => {
        console.log('文件b: ', data)
        readFileAsync('c.txt', (err, data) => {
          console.log('文件c: ', data)
          readFileAsync('d.txt', (err, data) => {
            console.log('文件d: ', data)
          })
        })
      })
    })
    
    • Promise 方式:将异步操作以同步操作的方式表达出来,避免了层层嵌套的回调函数
    readFileAsync('a.txt')
      .then(data => {
        console.log('文件a: ', data)
        return readFileAsync('b.txt')
      })
      .then(data => {
        console.log('文件b: ', data)
        return readFileAsync('c.txt')
      })
      .then(data => {
        console.log('文件c: ', data)
        return readFileAsync('d.txt')
      })
      .then(data => {
        console.log('文件d: ', data)
      })
    
    // 终极形态:
    async function fn() {
      const fileA = await readFileAsync('a.txt')
      console.log(fileA)
    
      const fileB = await readFileAsync('b.txt')
      console.log(fileB)
    
      const fileC = await readFileAsync('c.txt')
      console.log(fileC)
      
      const fileD = await readFileAsync('d.txt')
      console.log(fileD)
    }
    
    fn()
    

    三种状态

    • Promise 对象代表一个异步操作,有三种状态:pending(进行中)fulfilled(已成功)rejected(已失败)
      • 状态改变 1:pending -> fufilled
      • 状态改变 2:pending -> rejected
      • 一旦状态改变,就不会再变

    基本使用

    • Promise 构造函数:就是一个容器,用来封装异步操作
    // Promise 是一个构造函数
    // 通过 new 创建Promise的实例对象
    const p = new Promise(function(resolve, reject) {
      // resolve 表示成功,异步操作成功调用
      // reject  表示失败,异步操作失败调用
      fs.readFile('a.txt', (err, data) => {
        if (err) {
          // 文件读取失败,调用 reject
          reject(err)
          return
        }
    
        // 文件读取成功,调用 resolve
        resolve(data)
      })
    })
    

    then 和 catch

    • 说明:获取异步操作的结果
    • then() :用于获取异步操作成功时的结果 -> resolve
    • catch():用于获取异步操作失败时的结果 -> reject
    • 说明:then()方法可以有多个,按照先后顺序执行,通过回调函数返回值传递数据给下一个 then
    p
      // 成功
      .then(value => {
        console.log('文件a的内容为:', value)
      })
      // 失败(比如:文件路径错误)
      .catch(err => {
        console.log('文件读取失败:', err)
      })
    
    // ----------- 或者 -----------
    p.then(
      value => {
        // 成功
      },
      err => {
        // 失败
      }
    )
    

    all 和 race

    // 所有请求发送成功:
    const p = Promise.all([
      axios('http://vue.studyit.io/api/getlunbo'),
      axios('http://vue.studyit.io/api/getnewslist')
    ])
    
    p.then(function(res) {
      // res 是 all() 方法中所有异步操作的结果
      console.log('两个异步请求完成:', res)
    })
    
    // 哪个请求先发送成功:
    const p = Promise.race([
      axios('http://vue.studyit.io/api/getlunbo'),
      axios('http://vue.studyit.io/api/getnewslist')
    ])
    
    p.then(function(res) {
      // res 是 race() 方法中先完成的异步操作的结果:
      console.log('一个异步请求完成:', res)
    })
    

    Promise 的实现方式

    async 和 await

    • 异步编程终极方案
    • 注意:await只能在async函数中使用
    • 注意:await后面是一个Promise实例对象
    • 注意:await关键字用来暂停后面的函数,等到获取到结果后,下面的代码才会执行
      • 这样,就可以按照代码书写的顺序来理解代码执行顺序
    • 使用 ES2017 的 Async 功能
    • async/await 替代 Promise 的 6 个理由
    // 封装 Promise函数
    function timeout(ms) {
      return new Promise(resolve => {
        // setTimeout(resolve, ms, 'await')
        setTimeout(
          data => {
            resolve(data)
          },
          ms,
          '定时器'
        )
      })
    }
    
    // 使用 async关键字 创建一个异步函数
    async function fn() {
      console.log('await 前面')
    
      // 使用await关键字暂停函数,等待 Promise 的结果
      const ret = await timeout(3000)
      console.log(ret)
    
      console.log('await 后面')
    }
    
    fn()
    

    Promise 执行顺序问题

    let promise = new Promise(function(resolve, reject) {
      console.log('1 Promise')
      // 异步操作
      setTimeout(resolve, 1000, 'done')
    })
    
    promise.then(function() {
      console.log('3 resolved.')
    })
    
    console.log('2 Hi!')
    

    webpack 4.0 使用

    使用上的变化:
    1 需要单独安装 webpack-cli 才能使用 webpack命令
    2 使用webpack命令需要指定模式(development 或者 production)
    3 默认的入口为:./src/index.js  默认出口为:./dist
    

    说明

    • 1 webpack的默认入口为:/src/index.js
    • 2 webpack 两种模式(mode
      • 开发模式:development
      • 生成模式:production 压缩版
    • 指定入口:webpack ./src/main.js
    • 指定出口:webpack ./src/main.js -o ./dist/bundle.js

    相关文章

      网友评论

          本文标题:ES6(玺哥篇)

          本文链接:https://www.haomeiwen.com/subject/hfrfrqtx.html