前端进阶之旅前端进阶之旅
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
  • 基础篇HTML/CSS/JS 打底
  • 进阶篇原理与工程化
  • 高频篇面试最常问的那批
  • 精选篇按模块收敛的总结
  • 手写篇常考代码手写实现
  • 面经篇真实面试问题复盘
  • AI 篇NEWAI 时代的前端考点
  • 历年面经NEW按年份追踪真实考点
  • 每日一题每天一道,攒手感
  • 专项自测100 题快速查漏
  • 小程序题库小程序专项刷题
  • 算法题库NEW在线编码即时判题
  • 知识卡片NEW碎片时间过考点
  • 面试题大全常见问题解析
  • AI 答疑NEW随时提问,即时解析
  • AI 模拟面试NEW模拟真实面试 + 报告
  • AI 定制路线NEW按你的简历现排
  • AI 知识地图NEW串起全站知识点
  • 原理篇React / Vue 源码拆解
  • HTTP从报文一路讲到 HTTPS
  • 浏览器渲染、事件循环、进程
  • 计算机基础Linux、网络、操作系统
  • 设计模式23 种模式怎么用
  • Node学习指南从环境搭建到服务端
  • NPM工作流script、依赖与发布
  • Docker容器化部署上手
  • Canvas图形与动画实战
  • 前端系统进阶学习大型项目工程化
  • 前端综合文章长期沉淀的实践文
  • 思维导图知识点全景图
  • 学习路线按图索骥不跑偏
  • AI 热点NEWAI 每日动态
  • 公众号动态公众号历史文章
  • 博客动态站长的技术博客
  • 开发者导航常用工具与文档站
首页程序员面试题库事件处理函数 this 指向 addEventListener
JSJavaScript函数与作用域

在 DOM 事件处理函数中,this 指向什么?与 addEventListener 关联?

事件处理函数中普通函数的 this 指向监听器注册的元素(currentTarget),箭头函数的 this 则继承定义时的外层词法作用域,需按需选择。

前端进阶之旅 · 一题精讲更新于 2026.09.05
JavaScript#函数与作用域
先看核心答案
理解线索

事件监听中的 this 绑定机制

  1. 普通函数this 绑定为注册监听的元素
  2. 箭头函数this 等同于定义处外层 this
  3. event.currentTarget始终指向注册监听的元素

在捕获或冒泡阶段,currentTarget 是监听器所在元素,而 target 是最初触发事件的那个。

核心回答

先记住这个答案

当用 addEventListener 注册普通函数(function 声明或表达式)时,事件触发后该函数内的 this 会被绑定为 currentTarget,即调用 addEventListener 的那个元素。箭头函数没有自己的 this,它会捕获定义位置上外层作用域的 this 值,因此不会自动指向事件目标。若想获得目标元素,应使用 event.currentTarget 或采用普通函数。

  • 普通函数 this 指向监听器注册的元素(currentTarget)
  • 箭头函数 this 继承定义处的外层作用域
  • 需要当前元素时应使用 event.currentTarget
  • 回调提取为函数引用时 this 可能丢失

addEventListener 如何决定 this

当为元素调用 addEventListener(type, listener) 时,浏览器在注册阶段并不改变 listener 函数本身的 this。但当事件命中元素并触发回调时,内部会以该元素作为 this 值来调用 listener(若 listener 是普通函数)。这意味着普通函数内部可以通过 this 访问注册监听的元素本身,而不必再依赖 event.currentTarget。

如果 listener 是箭头函数,因为箭头函数在定义时已经固定了 this 词法值,所以 addEventListener 无法也无法更改其 this。箭头函数的 this 由外层作用域决定,例如在全局环境定义则 this 为 window(非严格模式),在对象方法中定义则 this 为该对象。因此使用箭头函数就丧失了动态 this 根据目标元素绑定的特性。

多按钮列表中的点击处理

假设有一个任务列表,每个按钮点击时需要获取对应的任务 ID 并更新其样式。如果用普通函数:document.querySelectorAll('.task-btn').forEach(btn => { btn.addEventListener('click', function() { this.classList.toggle('done'); }); }); 这里 this 就是被点击的按钮,可以立即操作 classList。同样的逻辑如果改写为箭头函数,this 不会指向按钮,而是继承定义处的外层词法 this,无法直接获取按钮元素。

正确的做法是在箭头函数内使用 event 参数:btn.addEventListener('click', (event) => { event.currentTarget.classList.toggle('done'); }); 因为箭头的 this 不可靠,但 event.currentTarget 永远指向注册监听的元素。对于需要动态作用域的简单回调,普通函数更简洁;箭头函数需要显式依赖事件对象时则更一致。

this 丢失与无法绑定的边界

当普通函数被作为回调传递时,this 可能会丢失。例如将对象方法直接作为监听器:element.addEventListener('click', this.handleClick); 此时回调内的 this 不再指向对象,而是指向元素(即注册监听的元素)。因为 addEventListener 以元素作为 this 调用该函数,破坏了原始绑定。使用 bind 可以修复:element.addEventListener('click', this.handleClick.bind(this))。

箭头函数则完全无法通过 bind 改变 this,因为箭头函数没有自己的 this,但可以借用事件对象的 currentTarget 来得到当前元素。遇到既需要动态目标元素又需要外层变量时,普通函数配合闭包变量,或箭头函数配合 event.currentTarget 都是可行方案,但要权衡代码可读性和性能:每次 bind 会产生新函数,移除监听器时需要保留引用。

回答前,多想一步

容易答错的地方

认为箭头函数中的 this 指向事件目标
实际箭头函数没有自己的 this,事件处理中它继承外层词法作用域的值,不会自动指向元素。若需获取当前注册元素,建议使用 event.currentTarget(或 event.target 针对触发元素),而不要依赖 this。很多初学者误将 this 与 event 参数混淆。
忽视 this 在回调传递中的变化
未使用 addEventListener 直接绑定普通函数时,this 取决于调用方式。如果从对象方法中提取函数后传入 addEventListener,该函数会被当作普通函数调用,this 指向元素,丢失对象引用。解决方法是用 bind 手动固定 this,或者改用箭头函数并通过 event 访问所需元素。
试着用自己的话回答

面试官还会怎么问?

在事件处理函数中,this 和 event.currentTarget 总是相同吗?

不一定。当监听器由 addEventListener 注册且以普通函数直接调用(未被 bind)时,this 与 event.currentTarget 相同,均指向注册监听的元素;但如果使用箭头函数或通过 bind 改变 this,则 this 与 event.currentTarget 可能不同,此时应依赖 event.currentTarget。

为什么对象方法直接作为事件监听器时 this 会丢失?

因为 addEventListener 内部将函数作为独立的回调,调用时 this 会被设置为事件目标元素(即注册监听的元素),而不是保存方法的对象。this 是调用时决定的,与定义的环境无关。要保留对象引用,需用 bind 或箭头函数包裹调用。

使用 React 合成事件时 this 绑定与原生 DOM 有何不同?

React 合成事件中,事件监听器是挂在根容器上的代理,但在类组件中,通过 JSX 绑定事件处理器时 React 不会自动把 this 绑定到组件实例,需要在构造函数中 bind 或使用箭头函数。原生 DOM 的 this 规则在 React 中不适用,因为 React 内部封装了事件传递。现在函数组件更倾向使用闭包和 hooks 避免 this 问题。

从一道题,走向一组知识

把知识连起来

函数与作用域

箭头函数中的 this 是如何决定的?为什么会词法绑定?

同属「函数与作用域」专题,接着看 箭头函数 this 词法绑定原理 在具体场景中的处理方式。

函数与作用域

Function.prototype.bind 与 call/apply 的区别是什么?bind 返回的新函数有哪些特性?

同属「函数与作用域」专题,接着看 bind 与 call apply 区别 在具体场景中的处理方式。

放回知识体系中复习JavaScript 进阶知识

参考资料

  • EventTarget: addEventListener() method

示例用于理解所注明的运行环境与边界;延伸学习可结合原文中的更多案例。

本题目录
  1. 先记住这个答案
  2. addEventListener 如何决定 this
  3. 多按钮列表中的点击处理
  4. this 丢失与无法绑定的边界
  5. 容易答错的地方
  6. 面试官还会怎么问
  7. 把知识连起来
读懂,再试着讲出来

先看核心答案,再读代码。最后展开追问,检查自己有没有遗漏边界。

试着回答追问
浏览全部面试题理解原理,也关注真实的使用场景。回到顶部 ↑