匿名函数传给 settimeout 后 this 是 window,因为其被作为独立函数调用,按默认绑定规则指向全局对象;箭头函数则继承外层词法作用域的 this。

匿名函数传给 setTimeout 后 this 为什么是 window
因为 setTimeout 内部把回调当作「独立函数调用」执行,不带任何调用者上下文。JavaScript 引擎在找不到明确调用对象时,就按默认绑定规则把 this 设为全局对象(非严格模式下是 window,严格模式下是 undefined)。
普通函数 vs 箭头函数在 setTimeout 中的 this 差异
关键区别在于:普通函数有自己运行时的 this 绑定逻辑;箭头函数根本没有自己的 this,直接沿用外层词法作用域的 this 值。
-
setTimeout(function() { console.log(this); }, 1000)→this是window(或undefined) -
setTimeout(() => { console.log(this); }, 1000)→this和外层函数一致,比如对象方法里就是那个对象
常见修复方式及适用场景
三种主流解法,效果一样但原理不同:
- 用变量暂存:
const self = this; setTimeout(function() { console.log(self.name); }, 1000)—— 依赖闭包,兼容性最好 - 用
bind显式绑定:setTimeout(function() { console.log(this.name); }.bind(this), 1000)—— 明确意图,但每次都要写.bind(this) - 改用箭头函数:
setTimeout(() => console.log(this.name), 1000)—— 最简洁,但要注意外层this必须已正确绑定(比如不能在全局作用域直接写)
容易被忽略的边界情况
即使你用了 bind 或箭头函数,如果外层函数本身 this 就没绑对,结果照样错:
- 直接调用
obj.method()→this是obj,没问题 - 但写成
const fn = obj.method; fn()→this变成window,再套setTimeout也救不回来 -
new构造出来的实例中,this.method被传进setTimeout,若没处理,内部this仍会丢失为window
真正要盯住的,从来不是 setTimeout 本身,而是「这个函数被谁、以什么方式调用」——它决定了第一层 this,而所有后续嵌套都从这里开始继承或丢失。










