箭头函数与传统的 JavaScript 函数有些不同,主要集中在以下方面:
没有 this、super、arguments 和 new.target 绑定:箭头函数中的 this、super、arguments 及 new.target 这些值由外围最近一层非箭头函数决定。
不能通过 new 关键字调用:箭头函数没有 [[Construct]] 方法,所以不能被用作构造函数,如果通过 new 关键字调用箭头函数,程序会抛出错误。
没有原型:由于不可以通过 new 关键字调用箭头函数,因而没有构建原型的需求,所以箭头函数不存在 prototype 这个属性。
不可改变 this 的绑定:函数内部的 this 值不可被改变,在函数的声明周期内始终保持一致。
不支持 arguments 对象:箭头函数没有 arguments 绑定,所以你必须通过命名参数和不定参数这两种形式访问函数的参数。
不支持重复的命名参数:无论在严格还是非严格模式下,箭头函数都不支持重复的命名参数;而在传统函数的规定中,只有在严格模式下才不能有重复的命名参数。
没有 this 绑定
var PageHandler = {
id: "123456",
init: function() {
document.addEventListener("click", function(event) {
this.doSomething(event.type); // error
}, false);
},
doSomething: function(type) {
console.log("Handling " + type + " for " + this.id);
}
};
上面的例子中,对象 PageHandler 是用来处理页面上的交互的,init 方法中定义了一个事件处理函数去调用 this.dosomething()
。由于 this 引用的是事件对象(事件对象中没有 doSomething()
函数),而不是对象 PageHandler,所以当事件处理函数被调用的时候,在运行到 this.doSomething()
时会报错。
上面的问题,可以通过箭头函数来处理。由于箭头函数没有 this 绑定,这意味着箭头函数中 this 的值是通过在作用域链上查找来决定的。如果箭头函数被包含在一个非箭头函数的函数中,则箭头函数的 this 与包含他的函数的 this 值相同。
var PageHandler = {
id: "123456",
init: function() {
document.addEventListener("click",
event => this.doSomething(event.type), false);
},
doSomething: function(type) {
console.log("Handling " + type + " for " + this.id);
}
};
上面的例子中,事件处理函数时通过箭头函数来改写,此时箭头函数的 this 值有外部的包含它的函数的 this 值来决定。因此,当,当事件处理函数被调用的时候,并不会出现报错。
没有 arguments 绑定
const arrowFunc = (a, b) => {
console.log('arguments', arguments)
}
arrowFunc(1, 2) // Uncaught ReferenceError: arguments is not defined