JavaScript中的this指向如何确定_箭头函数改变了什么

发布时间 - 2026-01-01 00:00:00    点击率:
普通函数的this由调用方式决定:独立调用指向window或undefined,对象方法调用指向该对象,构造调用指向新实例,事件监听中指向触发元素;箭头函数无this,继承外层普通函数的this且不可更改。

普通函数的 this 是在调用时确定的

JavaScript 中 this 不由函数定义位置决定,而取决于「谁调用它」。常见误区是以为写在哪、声明在哪就绑定哪,其实不是。

关键判断逻辑:看函数被调用时的「点号左边是谁」,或者是否用 call/apply/bind 显式指定。

  • 独立调用(如 foo()):非严格模式下指向 window(浏览器),严格模式下为 undefined
  • 对象方法调用(如 obj.method()):this 指向 obj
  • 构造函数调用(new Foo()):this 指向新创建的实例
  • 事件监听器中(btn.addEventListener('click', handler)):this 指向触发事件的 DOM 元素

箭头函数没有自己的 this,它继承外层作用域的 this

箭头函数不绑定 this,也不支持 call/apply/bind 改变它。它的 this 值在定义时就固定了,等于「上一级普通函数作用域中的 this」,或者全局作用域中的 this

这意味着:你不能靠调用方式改变箭头函数里的 this,也不能用 bind 修复它——它压根不接受。

立即学习“Java免费学习笔记(深入)”;

const obj = {
  name: 'Alice',
  regular() {
    console.log(this.name); // 'Alice'
    setTimeout(function () {
      console.log(this.name); // undefined(非严格模式下是 window)
    }, 100);
    setTimeout(() => {
      console.log(this.name); // 'Alice',继承 regular 的 this
    }, 100);
  }
};

容易踩坑的典型场景:事件回调和定时器里用错函数类型

当把对象方法传给异步操作(如 setTimeoutaddEventListenerPromise.then)时,普通函数会丢失原始 this,而箭头函数能保留——但前提是它定义在正确的上下文中。

  • 错误写法:setTimeout(obj.method, 100)method 被独立调用,this 失效
  • 正确做法之一:用箭头函数包裹:setTimeout(() => obj.method(), 100)
  • 正确做法之二:用 bind 绑定:setTimeout(obj.method.bind(obj), 100)
  • 注意陷阱:如果在类字段中写箭头函数(handler = () => { ... }),它的 this 指向类实例,但若该字段被解构后使用(const { handler } = obj; handler()),依然会保持原 this,这点和普通方法不同

class 中的箭头函数字段 vs 普通方法,this 表现不同

类中定义普通方法(method() {})时,this 是动态的;定义箭头函数字段(method = () => {})时,this 在实例化时就捕获并固化了。

这导致:前者可被重绑定(obj.method.call(other)),后者不可;后者适合做事件处理器,避免手动 bind,但也意味着无法通过 call 注入其他 this 上下文。

class Counter {
  count = 0;
  // 普通方法:this 动态
  increment() {
    this.count++;
  }
  // 箭头字段:this 在 new Counter() 时绑定到实例
  decrement = () => {
    this.count--;
  };
}

真正复杂的地方在于嵌套作用域链和类字段的组合——比如在 React 类组件中混用箭头函数字段和生命周期方法,this 看似稳定,实则依赖构造顺序和初始化时机。稍不注意,就会在异步回调里拿到过期的 this 或未初始化的实例属性。


# react  # javascript  # java  # 处理器  # 浏览器  # app  # win  # 作用域 


相关栏目: 【 网站优化151355 】 【 网络推广146373 】 【 网络技术251813 】 【 AI营销90571


相关推荐: EditPlus中的正则表达式 实战(4)  Python面向对象测试方法_mock解析【教程】  详解Android——蓝牙技术 带你实现终端间数据传输  Laravel Blade模板引擎语法_Laravel Blade布局继承用法  谷歌浏览器如何更改浏览器主题 Google Chrome主题设置教程  如何使用 jQuery 正确渲染 Instagram 风格的标签列表  微信小程序制作网站有哪些,微信小程序需要做网站吗?  如何快速生成专业多端适配建站电话?  如何用美橙互联一键搭建多站合一网站?  Swift中swift中的switch 语句  php结合redis实现高并发下的抢购、秒杀功能的实例  Laravel Facade的原理是什么_深入理解Laravel门面及其工作机制  百度浏览器网页无法复制文字怎么办 百度浏览器复制修复  如何基于云服务器快速搭建网站及云盘系统?  Laravel模型事件有哪些_Laravel Model Event生命周期详解  Laravel怎么创建自己的包(Package)_Laravel扩展包开发入门到发布  详解MySQL数据库的安装与密码配置  头像制作网站在线观看,除了站酷,还有哪些比较好的设计网站?  Laravel用户密码怎么加密_Laravel Hash门面使用教程  如何快速上传自定义模板至建站之星?  Laravel如何为API编写文档_Laravel API文档生成与维护方法  JavaScript如何实现错误处理_try...catch如何捕获异常?  米侠浏览器网页图片不显示怎么办 米侠图片加载修复  Laravel如何为API生成Swagger或OpenAPI文档  Laravel如何使用Service Provider注册服务_Laravel服务提供者配置与加载  微信小程序 HTTPS报错整理常见问题及解决方案  LinuxCD持续部署教程_自动发布与回滚机制  java中使用zxing批量生成二维码立牌  详解Android图表 MPAndroidChart折线图  javascript中闭包概念与用法深入理解  在线教育网站制作平台,山西立德教育官网?  Laravel如何实现事件和监听器?(Event & Listener实战)  iOS UIView常见属性方法小结  厦门模型网站设计制作公司,厦门航空飞机模型掉色怎么办?  如何在VPS电脑上快速搭建网站?  Laravel如何理解并使用服务容器(Service Container)_Laravel依赖注入与容器绑定说明  nodejs redis 发布订阅机制封装实现方法及实例代码  网站制作怎么样才能赚钱,用自己的电脑做服务器架设网站有什么利弊,能赚钱吗?  jQuery中的100个技巧汇总  佐糖AI抠图怎样调整抠图精度_佐糖AI精度调整与放大细化操作【攻略】  在Oracle关闭情况下如何修改spfile的参数  如何用搬瓦工VPS快速搭建个人网站?  如何用PHP快速搭建CMS系统?  JS经典正则表达式笔试题汇总  Gemini手机端怎么发图片_Gemini手机端发图方法【步骤】  Laravel如何集成Inertia.js与Vue/React?(安装配置)  🚀拖拽式CMS建站能否实现高效与个性化并存?  大连 网站制作,大连天途有线官网?  Laravel如何实现多语言支持_Laravel本地化与国际化(i18n)配置教程  Linux后台任务运行方法_nohup与&使用技巧【技巧】