JavaScript 的 this 指向取决于调用方式而非定义方式;普通函数直接调用时,非严格模式下指向 window,严格模式下为 undefined;箭头函数无自有 this,继承外层词法作用域的 this;call/apply/bind 可显式绑定 this,其中 bind 返回永久绑定新函数;new 调用时 this 指向新实例,且优先级最高,箭头函数不可 new 调用。

JavaScript 的 this 指向取决于函数**如何被调用**,而不是如何被定义;改指向本质是控制调用时的执行上下文。
普通函数调用时的 this 指向哪里
在非严格模式下,直接调用函数(如 foo()),this 指向全局对象(浏览器中是 window);严格模式下是 undefined。
常见错误现象:setTimeout(foo, 100) 或事件回调中 this 丢失,因为它们属于“普通调用”。
- 箭头函数没有自己的
this,它继承外层函数作用域的this(不是调用时决定的) - 对象方法赋值给变量后调用,
this会脱离原对象:const fn = obj.method; fn();→this不再是obj - 嵌套函数中,内层普通函数的
this不会自动绑定外层对象,需显式处理
用 call、apply、bind 改变 this
三者都用于显式指定函数执行时的 this 值,区别在于参数传递方式和是否立即执行:
立即学习“Java免费学习笔记(深入)”;
-
fn.call(obj, arg1, arg2):立即执行,参数逐个传入 -
fn.apply(obj, [arg1, arg2]):立即执行,参数以数组形式传入 -
const boundFn = fn.bind(obj, arg1):返回新函数,this被永久绑定为obj,可后续调用;已绑定的参数会前置(柯里化)
注意:bind 绑定后无法再通过 call/apply 覆盖 this(除非用 new 调用该绑定函数)。
箭头函数为什么不能改 this
箭头函数的 this 是词法绑定的——它在定义时就确定了,由外层第一个普通函数或全局作用域的 this 决定,之后任何调用方式都无法改变。
使用场景举例:
- 事件监听器中避免
this指向丢失:btn.addEventListener('click', () => this.handleClick()) - 定时器中保持实例上下文:
setTimeout(() => this.update(), 100) - 但不要用在需要动态
this的地方,比如作为对象方法被不同对象复用
如果外层是全局作用域,箭头函数的 this 就是 window(非严格)或 undefined(严格),这点容易被忽略。
new 调用时的 this 行为
用 new 调用构造函数时,this 指向新创建的实例对象。此时 this 的绑定优先级高于 call/apply/bind。
关键点:
- 即使对已
bind的函数再用new,this仍指向新实例,而非bind传入的对象 - 箭头函数不能用
new调用,会报错TypeError: xxx is not a constructor - 构造函数内部若返回对象,则
this实例会被忽略;返回原始值则不影响this实例
真正复杂的地方在于嵌套调用 + 箭头函数 + 绑定函数混用时,this 的来源可能跨多层作用域,必须逐层确认定义位置和调用方式。











