本文转载自公众号《阅读核心》(ID:AI_Discovery)ES6的箭头函数貌似是一个很容易上瘾的函数。一旦你了解它,你就可以轻松使用它并且无法停止。作为2015年ECMAScript6更新的一部分,箭头函数的流行是有充分理由的。箭头函数语法是一个优秀的语法糖,可以解决很多需求:函数关键字花括号return关键字(用于单行函数)此外,箭头函数还减少了JavaScript的函数作用域和this关键字的一些复杂性,因为有时真正需要的只是一个匿名函数。但事实是,箭头函数并不一定能解决编写JavaScript函数时的所有需求。“灵丹妙药”功能可谓奢侈。让我们深入研究箭头函数无法解决的几种情况。对象原型先看JavaScript代码片段:classRobot{constructor(name,catchPhrase){this.name=name;this.catchPhrase=catchPhrase;}};Robot.prototype.speak=()=>{console.log(this===window);returnthis.catchPhrase};constironG=newRobot("IronGiant","Begood");ironG.speak();第15行函数调用如下:trueundefined定义了speak()的原型函数,并且传递的是一个新的Robot对象Slogan,那么为什么这段代码求值为undefined?console.log()揭示了原因。可以看到,当让控制台判断(this===window)时,返回true。这为上面对象方法示例中讨论的内容提供了基础。使用需要上下文的函数时,必须使用常规函数语法以便正确绑定this:Robot.prototype.speak=function(){console.log(this===ironG);//truereturnthis.catchphrase;};对象方法假设您要创建一个绑定到对象的方法。constmario={lives:3,oneUp:()=>{this.lives++;}}在此示例中,如果调用mario.oneUp(),则mario.lives的值应从3增加到4。但是,随着代码写到此为止,无论oneUp()被调用多少次,lives的值都是一样的。为什么?正是因为这个!正如MDN所说:Arrow函数本身没有这个。使用封闭的词法范围内的this值;箭头函数遵循正常的变量查找规则。因此,当搜索当前作用域中不存在的this时,箭头函数最终会从其封闭作用域中找到this。在示例中,封闭范围是window对象。调用oneUp()将要求程序增加窗口对象中的lives值。这样的值不存在,因此代码不起作用。相反,应该使用传统的函数语法,它将函数的this绑定到调用该函数的特定对象:constmario={lives:3,oneUp:function(){this.lives++;}};动态上下文最后一个例子:constbutton=document.querySelector(#darkMode);button.addEventListener('click',()=>{this.classList.toggle('on');});到目前为止,您可能已经意识到此代码无效以及原因。是的,这又和这个有关。箭头函数语法在函数声明时静态绑定上下文,这与您在使用本质上是动态的事件处理程序或事件侦听器时试图实现的目标相反。当通过事件处理程序或侦听器操作DOM时,触发的事件指向属于目标元素的this。对于在全局执行上下文中定义的箭头函数,this将指向window。因此,在上面的代码中,this.classList会被认为是window.classList,从而导致TypeError。来源:unsplash从这几个简单的例子中可以发现,JavaScript中this的内容很值得研究,可能会加深你对什么时候使用,什么时候不使用箭头函数的理解。
