了解一下 es6 的箭头函数

箭头函数与普通函数的区别

  1. 箭头函数体内的this对象,就是定义时所在的对象,而不是使用时所在的对象。
  2. 箭头函数不可以当作构造函数,也就是说,不可以使用new命令,否则会抛出一个错误。
  3. 箭头函数不可以使用arguments对象,该对象在函数体内不存在。

在ES5中,函数作为对象的方法调用时,this指向的是调用的对象;而在ES6的箭头函数中,箭头函数没有自己的this, 它的this是继承而来; 默认指向在定义它时,它所处的对象而不是执行时的对象, 如果没有,就会一层层网上找,直到window, 但这也不是完全正确的箭头函数根本就没有绑定自己的 this,在箭头函数中调用 this 时,仅仅是简单的沿着作用域链向上寻找,找到最近的一个 this 拿来使用而已

箭头函数

箭头函数表达式的语法比函数表达式更短,并且不绑定自己的thisargumentssupernew.target。这些函数表达式最适合用于非方法函数,并且它们不能用作构造函数。 -来自 MDN

  • 所以当你定义一个箭头函数,在普通函数里常见的this、arguments 等是统统没有的, 如果能获取到arguments,那它一定是来自父作用域, 比如:
function foo() {
  return () => console.log(arguments[0])
}
foo(1, 2)(3, 4)
  • foo 执行之后得到一个函数去掉用, 打印的arguments 是父级的1

this 指向问题

箭头函数内部的this是词法作用域,由上下文确定的 在普通函数中这种写法肯定是可以输出1的, 但是在对象内使用箭头函数来定义方法,就会出现问题

let a = {
  foo: 1,
  bar: () => console.log(this.foo)
}
a.bar()

这里打印的 this.a 未能按照正常思路输出1, 而是打印 undefined, 因为箭头函数中的this并不是指向a这个对象。对象a并不能构成一个作用域,所以再往上到达全局作用域,this就指向全局作用域了, window 下是没有这个值的

这个问题在构造函数内也是同样的

function aFun() {
  this.foo = 1
}
aFun.prototype.bar = () => console.log(this.foo)
let a = new aFun()
a.bar() // 这里打印的也是 undefined, 因为 this 同样指向了全局作用域, 而不是指向了构造函数 `aFun`

在什么地方适合使用箭头函数

  1. 箭头函数适合于无复杂逻辑或者无副作用的纯函数场景下,例如用在map、reduce、filter的回调函数定义中;
  2. 不要在最外层定义箭头函数,因为在函数内部操作this会很容易污染全局作用域。最起码在箭头函数外部包一层普通函数,将this控制在可见的范围内;
  3. 箭头函数最吸引人的地方是简洁。在有多层函数嵌套的情况下,箭头函数的简洁性并没有很大的提升,反而影响了函数的作用范围的识别度,这种情况不建议使用箭头函数。

不适合箭头函数的时候

  1. 我们在需要动态上下文的地方不能使用箭头函数
  2. 定义需要动态上下文的函数,构造函数,需要this对象作为目标的回调函数以及用箭头函数难以理解的语句

以上部分内容摘抄自 少年,不要滥用箭头函数啊