箭头函数与传统的 JavaScript 函数有些不同,主要集中在以下方面:

  • 没有 this、super、arguments 和 new.target 绑定:箭头函数中的 this、super、arguments 及 new.target 这些值由外围最近一层非箭头函数决定。

  • 不能通过 new 关键字调用:箭头函数没有 [[Construct]] 方法,所以不能被用作构造函数,如果通过 new 关键字调用箭头函数,程序会抛出错误。

  • 没有原型:由于不可以通过 new 关键字调用箭头函数,因而没有构建原型的需求,所以箭头函数不存在 prototype 这个属性。

  • 不可改变 this 的绑定:函数内部的 this 值不可被改变,在函数的声明周期内始终保持一致。

  • 不支持 arguments 对象:箭头函数没有 arguments 绑定,所以你必须通过命名参数和不定参数这两种形式访问函数的参数。

  • 不支持重复的命名参数:无论在严格还是非严格模式下,箭头函数都不支持重复的命名参数;而在传统函数的规定中,只有在严格模式下才不能有重复的命名参数。

没有 this 绑定

  1. var PageHandler = {
  2. id: "123456",
  3. init: function() {
  4. document.addEventListener("click", function(event) {
  5. this.doSomething(event.type); // error
  6. }, false);
  7. },
  8. doSomething: function(type) {
  9. console.log("Handling " + type + " for " + this.id);
  10. }
  11. };

上面的例子中,对象 PageHandler 是用来处理页面上的交互的,init 方法中定义了一个事件处理函数去调用 this.dosomething() 。由于 this 引用的是事件对象(事件对象中没有 doSomething() 函数),而不是对象 PageHandler,所以当事件处理函数被调用的时候,在运行到 this.doSomething() 时会报错。

上面的问题,可以通过箭头函数来处理。由于箭头函数没有 this 绑定,这意味着箭头函数中 this 的值是通过在作用域链上查找来决定的。如果箭头函数被包含在一个非箭头函数的函数中,则箭头函数的 this 与包含他的函数的 this 值相同。

  1. var PageHandler = {
  2. id: "123456",
  3. init: function() {
  4. document.addEventListener("click",
  5. event => this.doSomething(event.type), false);
  6. },
  7. doSomething: function(type) {
  8. console.log("Handling " + type + " for " + this.id);
  9. }
  10. };

上面的例子中,事件处理函数时通过箭头函数来改写,此时箭头函数的 this 值有外部的包含它的函数的 this 值来决定。因此,当,当事件处理函数被调用的时候,并不会出现报错。

没有 arguments 绑定

  1. const arrowFunc = (a, b) => {
  2. console.log('arguments', arguments)
  3. }
  4. arrowFunc(1, 2) // Uncaught ReferenceError: arguments is not defined