es6基础(三)

ES6全称ECMAScript 6.0,部分浏览器不支持ES6,在应用程序的构建过程中需要使用babelES6转换为ES5. es6新特性:默认参数箭头函数模块化ProxyGenerator构造器函数Promise

函数的扩展

  • 默认参数 函数体内不能再使用let const声明形参 默认参数必须放在最后面

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    function fn(a=10, b=20){
    console.log(a, b)
    }
    fn() // 10 20
    fn(6) // 6 20
    fn(8, 9) // 8 9
    // 间隔传递默认参数可以使用 undefiend代替
    function f(x, y=7, z=43){
    return x + y + z
    }
    console.log(f(1, undefined, 20)) // 28
    // 函数体内不能再使用`let const`声明形参
    function fn(a){
    let a = 3; // Identifier 'a' has already been declared
    }
  • 作用域
    一旦设置了参数的默认值,函数进行声明初始化时,参数会形成一个单独的作用域,初始化结束,作用域就会消失,不设置默认值是不会出现的

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    let x = 1
    function fn (x, y = x) {
    console.log(y)
    }
    // 参数y设置默认值等于x,调用fn形成单独的作用域,在作用域内,x指向第一个参数,而不是全局的变量x
    fn(2) // 2
    let a = 1
    function fn(b = a) {
    let a = 2
    console.log(b)
    }
    /* 函数fn调用时,参数b=a形成单独的作用域,在作用域内,变量a没有定义,
    指向外层的全局变量a,函数体内的局部变量a不会影响默认值变量a */
    fn() // 1
    var x = 1
    /* 函数foo的默认参数形成单独的作用域,在此作用域内,首先声明变量x和y,匿名函数y内部的变量x指向此作用
    域内的第一个参数x,函数foo内部的变量x也指向了第一个参数x,与匿名函数内部的x是一致的,执行y()后,将参
    数x修改为2,外部的全局变量依然不受影响,若将foo内部的x=3修改为 var x=3,则输出的是3 */
    function foo (x, y = function () { x = 2}) {
    x = 3
    y()
    console.log(x)
    }
    foo() // 2
    console.log(x) // 1
  • 函数的rest参数(…参数名) 剩余参数
    Spread Operator扩展运算符(…实参) 和 Rest Parameter(…形参) 是形似但相反意义的操作符,Rest Parameter 是把不定的参数“收敛”到数组,而 Spread Operator 是把固定的数组内容“打散”到对应的参数
    用于获取函数的多余参数,这样就不需要使用arguments对象了rest参数搭配的变量是一个数组,该变量会把多余的参数放入数组中.后边不能再有其他参数,否则会报错

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    function sum(...arr) {
    console.log(arr) // [1, 2, 3, 4, 5]
    let res = 0
    arr.map((item) => {
    res+=item
    })
    console.log(res)
    }
    sum(1, 2, 3, 4, 5) // 15
    function sum1(arg, ...arr) {
    console.log(arr) // [2, 3, 4, 5]
    let res = arg
    arr.map((item) => {
    res+=item
    })
    console.log(res)
    }
    sum1(1, 2, 3, 4, 5) // 15
    // Spread Operator(扩展运算符)
    function sum5 (x = 1, y = 2, z = 3) {
    return x + y + z
    }
    console.log(sum5(...[4]))// 9
    console.log(sum5(...[4, 5]))// 12
    console.log(sum5(...[4, 5, 6]))// 15

箭头函数

使用 => 定义函数 箭头左边是参数 右边是函数体

  • 基本用法 只有一个参数和函数体只有return一条语句时可简写

    1
    2
    3
    4
    5
    6
    // 只有一个参数时  () 可省略 只有一句return时 {} return也可省略
    const es6Fun = a => a
    // 等价于
    const es5Fun = function(a) { return a }
    console.log(es6Fun(1)) // 1
    console.log(es5Fun(1)) // 1
  • 有多个参数时 用()将参数包起来

    1
    2
    const fun = (a,b) => a + b
    console.log(fun(1, 2)) // 3
  • 函数体有多行代码时 要将多行代码用{}包起来

    1
    2
    3
    4
    5
    6
    const fun = (a, b) => {
    a = a*a
    b = b*b
    return a + b
    }
    console.log(fun(2, 3)) // 13
  • 当函数体只有一行return语句且返回的是字面量对象 ,要用()将返回值包起来

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    const fun2 = (a, b) => ({a,b})
    console.log(fun2(1, 2)) // {a:1, b:2}
    // es5 排序实例
    var arr = [5,1,3]
    arr.sort(function(a,b){
    return b - a
    })
    console.log(arr) // [5, 3, 1]
    // es6 箭头函数 排序实例
    arr.sort((a, b) => a - b)
    console.log(arr) // [1, 3, 5]
  • 箭头函数使用注意事项

    1. 箭头函数不可以使用yield,不能用作Generator生成器函数
    2. 函数体内没有自己的this对象,内部this对象是定义时上下文(外层作用域)的this对象, 不是调用时的this对象. 不能使用call apply bind去更改其内部的this指向.箭头函数中的this只取决包裹箭头函数的第一个普通函数的this

      1
      2
      3
      4
      5
      6
      7
      8
      9
      function fn(){
      console.log(this)
      return () => {
      console.log(this) // 定义时作用域
      }
      }
      // fn()() // Window window
      fn().call({a:2}) // Window window 无法使用 call 改变箭头函数this对象
      // fn.call({a:1})() // {a: 1} {a: 1}
    3. 箭头函数体内没有arguments对象,可以用rest参数代替

      1
      2
      3
      4
      5
      6
      7
      8
      let fun3 = (...rest) =>{
      console.log(rest)
      }
      fun3(1,2) // [1, 2]
      let fun4 = () => {
      console.log(arguments)
      }
      fun4(1,2) // arguments is not defined
    4. 箭头函数不可以当做构造函数,不可以使用new命令,否则会报错

      1
      2
      const Fun = (a, b) => a + b
      new Fun(1,2) // Fun is not a constructor

模块化

  • es6中每一个模块就是一个文件,希望外部可以读取模块中的内容,就必须使用export将其暴露出去(导出), 子其他模块使用import导入

    1
    2
    3
    4
    5
    // a.js
    export const name = 'tew'
    // b.js
    import { name } from './a.js'
    console.log(name) // tew
  • 如果要导出多个变量可以将这些变量包装成对象进行模块化导出

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // a.js
    let name = 'tew'
    let age = 18
    let fn = (name) => `My name is ${name}`
    export { name, age, fn }
    // b.js
    import { name, age, fn } from './a.js'
    console.log(fn('Bob')) // My name is Bob
    console.log(age) // 18
  • 使用as对导出变量或导入变量进行重命名

    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    // a.js
    let name = 'tew'
    let age = 18
    let fn = (name) => `My name is ${name}`
    export { name as myName, age, fn as myFn }
    // b.js
    import { myName as name, age, myFn as fn } from './a.js'
    console.log(name) // tew
    console.log(fn('Bob')) // My name is Bob
    // 直接导入整个模块
    // import * as info from './a.js'
    // console.log(info.name) // tew
  • 默认导出 一个模块只能有一个export default默认导出

    1
    2
    3
    4
    5
    export default function(){
    return '默认导出'
    }
    import fn from './a.js'
    console.log(fn()) // 默认导出
  • 混合导出 同时有exportexport default

    1
    2
    3
    4
    5
    6
    7
    8
    9
    // a.js
    export default function(){
    return '默认导出'
    }
    export let name = 'tew'
    // b.js
    import fn, {name} from './a.js'
    console.log(fn()) // 默认导出
    console.log(name) // tew

Proxy

proxy用于修改某些操作的默认行为,在目标对象架设一层拦截,访问该对象时,都必须先通过这层拦截,可以对访问进行过滤和改写

  • 基础用法
    1
    2
    // var proxy = new Proxy(target, handler)
    // new Proxy() 生成一个proxy实例,target表示所要拦截的目标对象,handle对象参数用来定制拦截行为

Generator构造器函数

Generator函数是ES6提供的一种异步编程解决方案,是一个状态机,封装了多个内部状态,返回一个遍历器对象,可以依次遍历Generator函数内部的每一个状态

  • Generator函数的定义
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    // 1. Generator函数是一个普通函数,function关键字与函数名之间有一个星号 *
    function * foo () {...}
    function *foo () {...}
    function* foo () {...}
    function*foo () {...}
    // 由于没有规定 星号 * 的位置所以上述四种写法都可以使用
    // 2. 函数内部使用yield表达式,定义不同的内部状态
    function* helloGenerator() { // 定义三个状态 hello world ending
    yield 'hello'
    yield 'world'
    return 'ending'
    }
    // 调用Generator函数后,该函数并不执行,返回的也不是运行结果,而是指向内部状态的指针对象(遍历器对象)
    var hg = helloGenerator()
    // 调用遍历器对象的next方法,使得指针移向下一个状态,每次调用next内部指针就从上一次状态开始执行,直到遇到下一个yield或return
    hg.next() // {value: 'hello', done: false}
    hg.next() // {value: 'world', done: false}
    hg.next() // {value: 'ending', done: true}
    hg.next() // {value: undefined, done: true}
    /* 调用Generator函数,返回一个遍历器对象,代表内部指针,每次调用next方法,会返回value和done两个属性的对象,
    value表示当前yield表达式的值,done属性表示遍历是否结束, 遇到yield表达式,暂停执行后面的操作,并将紧跟在yield
    后面的表达式的值,作为返回对象的value值,遇到return语句,将return后面表达式的值作为返回对象value的值,并将done
    属性设置为true,如果没有return语句,则返回对象的value值为undefined,done属性为true */
    // for...of 循环可以自动遍历 Generator函数 生成的 Iterator 对象,且不需要调用next方法
    for (let v of helloGenerator()) {
    console.log(v)
    }
    // hello world // 一旦next方法返回的对象的done属性为true,循环就会中止,且不包含该对象(即不包含ending)
-------------本文结束感谢您的阅读-------------
0%