箭头函数能作为事件监听的回调函数吗?

1,094 阅读4分钟

携手创作,共同成长!这是我参与「掘金日新计划 · 8 月更文挑战」的第 16 天,点击查看活动详情

大家好,我是爱吃鱼的桶哥Z。在ES6普及后,箭头函数已经被我们高频使用了,那么你知道箭头函数能够作为事件监听函数的回调吗?今天我们就一起来探讨一下关于js中箭头函数的相关知识点,让我们开始吧!

箭头函数

首先,我们一起来了解一下箭头函数箭头函数JavaScript ES6引入的一种新的定义和编写函数的方法,虽然它看起来像是常规函数的语法糖,但是它与普通的函数有一个关键的不同之处,那就是this(上下文)的绑定不同。关于this的指向问题,你可以去阅读《JavaScript 高级程序设计》(第四版)这本书,书中介绍的还是比较详细的,这里就不对this的指向问题做过多的介绍。总之我们需要理解的就是:箭头函数是没有自己的this指向的,因此它本身的指向就根据它当前所在的上下文有关。

事件监听函数

我们一般在web开发中如果要给某个元素添加事件,都会用到addEventListener,下面我能看一个常规的例子,如下:

const toggleEle = document.querySelectorAll('.toggle');

toggleEle.forEach(ele => {
    ele.addEventListener('click', function () {
        this.classList.toggle('active');
    });
});

在上面的例子中,我们使用NodeList.prototype.forEach()来遍历元素的节点,并使用addEventListener将普通函数用作click事件的回调函数,以便在所点击的元素的状态中进行切换。因为这里我们使用的是普通的函数,所以函数的回调中this的指向就是当前的上下文,即这个点击的元素本身,因此我们才能改变这个元素的状态。

箭头函数作为回调函数

在前面我们介绍了箭头函数本身是没有this指向的,那么,如果我们把上面的代码中的普通函数换成箭头函数,会发生什么呢?箭头函数的上下文指向的是当前的全局对象,在这个例子就中是当前的window

让我们将上面的代码进行一个改造,代码如下:

const toggleEle = document.querySelectorAll('.toggle');

toggleEle.forEach(ele => {
    ele.addEventListener('click', () => {
        // 这里会报错,因为这里的this执行的是全局的window,而window上是没有classList的
        this.classList.toggle('active');
    });
});

在上述的代码中,当元素被点击时,会去改变这个元素的样式,但是由于window对象中没有classList这个属性,因此这里就会报错。一般当我们对this的指向问题搞不明白的时候,往往就会因为这个错误一直在这里进行debug,很多人对this的指向问题就经常分不清,导致在开发中产生很多问题。

其实,当我们遇到这样的问题时,我们只需要找到当前对象的上下文,及谁调用它,它就指向谁,就能很好的解决this的指向问题。在上述的代码中,我们只需要使用回调函数的第一个参数event就可以解决,在event中我们可以获取到event.target或者event.currenTarget,这样我们就能给当前的元素添加相应的内容了,修改后的代码如下:

const toggleEle = document.querySelectorAll('.toggle');

toggleEle.forEach(ele => {
    ele.addEventListener('click', (event) => {
        event.currenTarget.classList.toggle('active');
    });
});

我们通过event获取当点击被点击的元素,这样就脱离了this的指向问题,因为你点击的是谁,event是一定能够获取到你点击的这个对象的,因此当我们使用箭头函数也好,普通函数也好,都可以使用这样的方式来获取到我们点击的对象,以此再进行相关的操作就可以了。

最后

我们要搞清楚箭头函数中的this的指向问题,并且搞清楚箭头函数跟普通函数的区别在哪里,以及在事件绑定函数中,我们可以通过事件的event参数来获取当前被执行的元素,这样就不会被this执行的问题绕晕了,那么你现在知道下次再遇到这样的问题时该怎么解决了吗?

最后,如果这篇文章有帮助到你,❤️关注+点赞❤️鼓励一下作者,谢谢大家

往期回顾

用操作数组的方式来操作对象,该怎么做?

这几个数组的操作方法你必须知道

JS中这几种数组的操作方法你知道吗?