作者:DmitriPavlutin译者:前端小智来源:DmitriPavlutin点赞再看,微信搜索【大千世界】,B站关注【前端小智】这个没有大厂背景,但具有积极向上趋势心态的人。本文已收录到GitHubhttps://github.com/qq44924588...,文章已分类,也整理了很多我的文档和教程资料。最近开源了一个Vue组件,但是还不够完善。欢迎大家一起完善,也希望大家能给个star支持一下。谢谢。github地址:https://github.com/qq44924588...这些年,ES6把JS的易用性提升到了一个新的高度:箭头函数,类等等,这些都很棒。箭头函数是最有价值的新特性之一,有许多很好的文章描述了它们的上下文透明性和简短语法。但是每笔交易都有两个方面。通常,新功能会带来一些混乱,其中之一就是箭头函数被误导了。本文将介绍一些您应该绕过箭头函数以支持良好的旧函数表达式或较新的速记语法的场景。并注意缩短代码,因为这会影响代码的可读性。1.在对象上定义方法在JS中,方法是存储在对象属性中的函数。当方法被调用时,this将指向该方法所属的对象。对象字面量有一个简短的箭头函数语法,所以用它来定义方法很有吸引力。让我们试试看:constcalculate={array:[1,2,3],sum:()=>{console.log(this===window);//=>truereturnthis.array.reduce((result,item)=>result+item);}};console.log(这个===窗口);//=>true//抛出“TypeError:无法读取未定义的属性‘reduce’”calculate.sum();calculate.sum方法是用箭头函数定义的。但是在调用时,calculate.sum()会抛出TypeError,因为this.array是未定义的。在计算对象上调用方法sum()时,上下文仍然是窗口。发生这种情况是因为箭头函数在词法上将上下文范围限定为window对象。实现this.array等同于window.array,它是未定义的。解决方法是使用正则函数表达式来定义方法。这是在调用时确定的,而不是由封闭的上下文确定的,请参阅固定版本:constcalculate={array:[1,2,3],sum(){console.log(this===calculate);//=>truereturnthis.array.reduce((result,item)=>result+item);}};calculate.sum();//=>6因为sum是一个常规函数,所以在This是调用calculate.sum()时的calculate对象。this.array是一个数组引用,因此可以正确计算元素的总和:6.对象原型同样的规则适用于在原型对象上定义的方法。使用箭头函数定义sayCatName方法,this指向windowfunctionMyCat(name){this.catName=name;}MyCat.prototype.sayCatName=()=>{console.log(this===window);//=>truereturnthis.catName;};constcat=newMyCat('Mew');cat.sayCatName();//=>undefined使用早期定义函数表达式的方式:functionMyCat(name){this.catName=name;}MyCat.prototype.sayCatName=function(){console.log(this===cat);//=>truereturnthis.catName;};constcat=newMyCat('Mew');cat.sayCatName();//=>'Mew'sayCatName常规函数在作为方法调用时将上下文更改为cat对象:cat.sayCatName()。2.具有动态上下文的回调函数这是JS中一个强大的特性,它允许上下文根据函数的调用方式而改变。通常,上下文是调用发生的对象,这使得代码更自然,就好像这个对象发生了什么事一样。但是箭头函数会将上下文静态绑定在声明上,不能动态绑定,但是这种做法有坏处也有好处,有时候我们需要动态绑定。将事件侦听器附加到DOM元素是客户端编程中的一项常见任务。该事件触发处理函数并将其用作目标元素。如果在这里使用箭头函数,不够灵活。以下示例尝试为此类处理程序使用箭头函数:constbutton=document.getElementById('myButton');button.addEventListener('click',()=>{console.log(this===window);//=>truethis.innerHTML='Clickedbutton';});在全局上下文中,this指向窗口。当单击事件发生时,浏览器会尝试使用按钮上下文调用处理函数,但箭头函数不会更改其预定义的上下文。this.innerHTML等同于window.innerHTML,没有任何意义。必须应用函数表达式,它允许根据目标元素更改它:constbutton=document.getElementById('myButton');button.addEventListener('click',function(){console.log(this===button);//=>truethis.innerHTML='Clickedbutton';});当用户单击按钮时,处理函数中的this指向按钮。因此问题。innerHTML='Clickedbutton'正确修改按钮文本以反映单击状态。3.调用构造函数这是在构造调用中新创建的对象。执行newMyFunction()时,构造函数MyFunction的上下文是一个新对象:thisinstanceofMyFunction===true。请注意,箭头函数不能用作构造函数。JavaScript通过抛出异常来隐式地阻止这种情况。无论如何,这是来自封闭上下文的设置,而不是新创建的对象。换句话说,箭头函数构造函数调用没有意义,而且是模棱两可的。让我们看看如果我们尝试这样做会发生什么:constMessage=(text)=>{this.text=text;};//抛出“TypeError:Messageisnotaconstructor”consthelloMessage=newMessage('HelloWorld!');执行newMessage('HelloWorld!'),其中Message是箭头函数,JavaScript抛出TypeError错误,Message不能作为构造函数。上面的例子可以使用函数表达式来修复,这是创建构造函数(包括函数声明)的正确方法:constMessage=function(text){this.text=text;};consthelloMessage=newMessage('HelloWorld!');速记语法箭头函数有一个很好的特性,即它们可以省略参数括号()、块花括号{},如果函数体只有一条语句则返回。这有助于编写非常短的函数。原作者的大学编程教授给了学生一个有趣的任务:用C语言编写最短的函数来计算字符串的长度,这是学习和探索一门新语言的好方法。然而,在实际应用程序中,许多开发人员阅读代码。最短的语法并不总是适合帮助您的同事立即理解该方法的用途。速记函数有时会变得难以阅读,所以尽量不要过度使用。给大家看个例子constmultiply=(a,b)=>b===undefined?b=>a*b:a*b;常量双=乘法(2);双(3);//=>6multiply(2,3);//=>6multiply返回两个数的乘法结果或绑定到第一个参数的闭包,用于后续的乘法运算。该功能运行良好,看起来很短。但是很难从一开始就理解它的作用。为了使其更具可读性,从箭头函数中恢复可选的大括号和return语句,或使用常规函数:}}返回一个*b;}constdouble=multiply(2);double(3);//=>6multiply(2,3);//=>6findonebetweenshortandlong使代码更直观是一个很好的平衡。总结毫无疑问,箭头函数是一个很好的补充。正确使用时,可以很容易地使用.bind()或尝试更早地捕获上下文,它还简化了代码。在某些情况下的优势在其他情况下可能是劣势。当需要动态上下文时不能使用箭头函数:定义方法,使用构造函数创建对象,处理事件时从中获取目标。代码部署后可能存在的bug,无法实时获知。事后为了解决这些bug,花费了大量的时间在日志调试上。顺便推荐一个好用的bug监控工具Fundebug。原文:https://dmitripavlutin.com/wh...交流文章每周更新。可以微信搜索“大千世界”阅读即时更新(比博文早一两篇)。这篇文章在GitHubhttps://github.com/qq449245884/xiaozhi已经收录,整理了很多我的文档。欢迎star和改进。可以参考考点面试。另外,关注公众号,后台会回复福利,看到福利就知道了。
