JavaScript中的this指向什么_它在不同情况下如何变化

11次阅读

普通函数调用时this指向全局对象undefined;箭头函数不绑定this,继承外层词法作用域;对象方法中this指向调用者,赋值后退化为普通调用;dom事件中默认指向触发元素;call/apply/bind可显式控制this;new调用时this指向新实例;类方法遵循常规规则,但异步回调易丢失this。

JavaScript中的this指向什么_它在不同情况下如何变化

普通函数调用时,this 指向全局对象或 undefined

在非严格模式下,function foo() { console.log(this); } 直接调用 foo()this 指向 window浏览器)或 globalThisnode.js);严格模式下则为 undefined。这是最容易误判的起点——它和定义位置无关,只看「谁调用」。

  • 箭头函数不绑定 this,它继承外层作用域this 值,无法通过 call/apply/bind 修改
  • 对象方法中,this 指向调用该方法的对象,但一旦把方法赋值给变量(如 const fn = obj.method;),再调用就退化为普通函数调用
  • DOM 事件处理函数中,this 默认指向触发事件的元素(Event.currentTarget),但若用箭头函数写法,则 this 是外层词法作用域的值,不是元素本身

call、apply、bind 显式控制 this 指向

这三个方法本质都是手动指定函数执行时的 this 值。区别在于参数传递方式:call 接逗号分隔参数,apply 接数组,bind 返回新函数(this 被固化,后续调用不可再改)。

  • bind 返回的函数如果是箭头函数,则 this 仍由外层决定,bind 无效
  • 构造函数调用(new Foo())时,this 指向新创建的实例,此时 call/apply 会被忽略
  • es6 类的 constructor 和普通方法默认是“非箭头函数”,所以 this 行为符合常规对象方法规则

箭头函数的 this 是词法绑定,不是动态绑定

箭头函数没有自己的 this,它从定义时所在的作用域链中向上查找 this 值,并永久绑定。这意味着你不能用 call 改变它,也不能用 new 实例化它(会报 TypeError: Arrow functions are not constructors)。

const obj = {   name: 'test',   regular() {     return this.name; // 'test'   },   arrow: () => {     return this.name; // undefined(全局作用域中 this 没有 name)   },   wrapper() {     const innerArrow = () => this.name;     return innerArrow(); // 'test' —— 因为外层 regular 的 this 是 obj   } };

class 中的 this 绑定需警惕异步和回调场景

类方法内部的 this 指向实例没问题,但一旦传入定时器、事件监听或 promise 回调,就可能丢失。常见修复方式有三种:在 constructor 中用 bind、使用箭头函数属性(handleClick = () => { ... })、或在 jsX 中内联调用(onClick={() => this.handleClick()})。

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

  • 内联写法每次渲染都创建新函数,可能影响 react.memo 或 shouldComponentUpdate 判断
  • 类字段箭头函数是 ES2022 提案,已广泛支持,但要注意它在构造函数之前运行,此时 this 已存在,但某些初始化逻辑(如 super() 后才有的属性)可能尚未赋值
  • 如果方法需要访问 event,又想保持 this 指向实例,优先选 bind 或类字段箭头函数,避免内联

真正容易出问题的,不是 this 的规则本身,而是「你以为它在某个上下文里,其实它早就被上一层函数或调用方式悄悄劫持了」。尤其在组合函数、高阶组件、事件委托这些场景里,this 的归属常常比想象中更脆弱。

text=ZqhQzanResources