1. 箭头函数和普通函数的区别

    (1)箭头函数比普通函数更简洁:

    • 如果只有一个参数,不用写括号只用写参数
    • 如果只有返回值一句,不用写大括号只用写函数体
    • 可以使用 void 语句来避免返回
      1. let fn1 = a => { return a + 1 }
      2. let fn2 = (a, b) => a + b
      3. let fn3 = () => void doesNotReturn()
      (2)箭头函数没有自己的 this:只会在自己作用域的上一层继承 this,所以箭头函数的 this 的指向在定义时已经确定了
      (3)箭头函数继承来的 this 指向永远不会改变:箭头函数中的 this 永远指向它所定义时所处的全局执行环境的 this
      (4)call、apply、bind 等方法不能改变箭头函数中的 this 的指向:this 不可变动
      (5)箭头函数不能作为构造函数使用:没有自己的 this,也没有 prototype
      (6)箭头函数没有自己的 arguments:不能访问 arguments 类数组对象
      (7)箭头函数没有 prototype
      (8)箭头函数不能用作 Generator,不能使用 yield 关键字
    区别 箭头函数 普通函数
    this 指向 指向静态上下文 可以修改
    构造函数
    call、apply、bind 不能改 this,但可以绑定 可以改 this 和绑定
    构造函数
    arguments
    prototype
    Generator 函数关键字
    1. 箭头函数的 this 指向哪里?

    箭头函数并没有自己的 this,因此它所谓的 this 捕获其声明时的上下文,即这个 this 指向箭头函数定义的位置,即箭头函数外层的静态作用域。也因此箭头函数不会被 new 调用,这个 this 也不可能被更改

    1. const obj = {
    2. getArrow() {
    3. return () => {
    4. console.log(this === obj)
    5. }
    6. }
    7. }
    8. // babel 转化后
    9. var obj = {
    10. getArrow: function getArrow() {
    11. var _this = this
    12. return function () {
    13. console.log(_this === obj)
    14. }
    15. }
    16. }
    1. 扩展运算符的作用及使用场景

    (1)对象扩展
    对象的扩展运算符用于取出对象中所有可遍历属性,拷贝到外层的对象之中

    1. let bar = { a:1, b:2 }
    2. let baz = { ...bar }
    3. // 等价于
    4. let bar = { a:1, b:2 }
    5. let baz = Object.assign({}, bar) // { a:1, b:2 }

    如果目标对象与源对象有同名属性,或多个源对象有同名属性,则后面的属性会覆盖前面的属性
    Object.assign(target, source),assign 会把 source 源对象的所有可枚举属性,复制到 target 目标对象上, target 目标对象最终会被返回
    扩展运算符对对象的拷贝属于浅拷贝

    (2)数组扩展
    数组的扩展运算符可以将一个数组转为逗号分隔的参数序列,且每次只能展开一层数组

    1. [...[1, 2, 3]] /// [1, 2, 3]
    2. [...[1, [2, 3, 4], 5]] /// [1, [2, 3, 4], 5]

    应用:

    • 将数组转换为参数序列

      1. function add(x, y) {
      2. return x + y
      3. }
      4. const numbers = [1, 2]
      5. add(...numbers)
    • 复制数组

      1. const arr1 = [1, 2]
      2. const arr2 = [...arr1]
    • 合并数组

      1. const arr1 = ['two', 'three']
      2. const arr2 = ['one', ...arr1, 'four', 'five']
    • 扩展运算符合结构运算符结合,用于生成数组,注意扩展运算符用于数组赋值,只能放在参数的最后一位,否则会报错

      1. const [ first, ...rest ] = [1,2,3,4,5]
      2. first // 1
      3. rest // [2, 3, 4, 5]
    • 将字符串转为真正的数组,类似 split

      1. [...'hello'] // ['h','e','l','l','o']
    • 任何 iterator 接口的对象,都可以用扩展运算符转为真正的数组

      1. // 转化类数组等其他数据结构,到数组
      2. // 可以用于替换 es5 的 Array.prototype.slice.call(arguments) 写法
      3. function foo() {
      4. const args = [...arguments]
      5. }