全局执行上下文的this始终指向全局对象(浏览器为window,Node.js为global),函数执行上下文的this则取决于调用方式:对象方法调用指向该对象,独立调用在非严格模式下为window、严格模式下为undefined,显式绑定由call/apply/bind指定,构造调用指向新实例;箭头函数不绑定this,继承外层。

全局执行上下文中的 this 始终指向全局对象(浏览器中是 window,Node.js 中是 global),而函数执行上下文中的 this 没有固定值,完全取决于函数**如何被调用**——它在函数实际执行那一刻才确定,与函数定义位置、所在作用域无关。
全局执行上下文的 this:静态且唯一
只要代码不在任何函数体内,就处于全局执行上下文。此时 this 在创建阶段就被绑定为全局对象:
- 浏览器中执行
console.log(this),输出window; - 用
var x = 1声明的变量会自动成为window.x,等价于this.x = 1; - 即使在模块脚本(
type="module")或严格模式下,全局上下文的 this 仍为window(注意:模块顶层的this是undefined,但那是模块环境,不属于标准全局执行上下文)。
函数执行上下文的 this:动态且多变
每次函数被调用,都会创建新的函数执行上下文,其中 this 的值由调用方式决定,主要有以下四类:
-
对象方法调用:如
obj.fn(),this 指向obj; -
独立函数调用:如
fn()(无点号、无 call/apply/bind),非严格模式下 this 是window,严格模式下为undefined; -
显式绑定调用:用
fn.call(obj, ...)、fn.apply(obj, [...])或fn.bind(obj),this 强制指向指定对象; -
构造函数调用:用
new Fn()调用时,this 指向新创建的实例对象。
关键区别:绑定时机与可变性
全局上下文的 this 是“一次性绑定”,从上下文创建起就固定;而函数上下文的 this 是“运行时绑定”,同一函数多次调用可能产生不同 this 值:
- 一个函数赋值给不同对象后调用:
obj1.method = fn; obj2.method = fn;,则obj1.method()和obj2.method()中的 this 分别指向obj1和obj2; - 函数被提取后独立调用会导致 this 丢失(隐式绑定失效),例如
const f = obj.fn; f();—— 此时 this 不再是obj; - 箭头函数不创建自己的执行上下文,也不绑定 this,它直接继承外层普通函数或全局上下文的 this 值。
小结:记住核心逻辑
判断 this,先看执行上下文类型,再看函数调用形式。全局上下文只有一种情况,this 必为全局对象;函数上下文必须回溯到调用那一行代码——有没有点号?有没有 new?有没有 call/apply/bind?没有就按默认规则走。这不是语法糖,而是 JavaScript 运行时机制的本质体现。

















