JS 全局环境和对象调用中的 this 指向?
· 3 min read
this 指向在函数定义时不确定,调用时才确定。
- 全局环境:浏览器
this === window,Node 中this === global,严格模式为undefined - 对象方法:
obj.method()中 this 指向点号左侧的对象 - 独立调用:函数脱离对象后丢失绑定,this 回退到全局(严格模式 undefined)
- 箭头函数:没有独立的 this,捕获定义时所在作用域的 this
- 显式绑定:
call/apply/bind可手动指定任意 this
核心原则:只看如 何调用,不看在哪定义。
this 的规则其实不复杂,复杂的是总有人想用直觉去理解它。记住一条:this 在函数定义时不确定,调用时才确定。
全局环境
浏览器顶层代码里 this === window,Node.js 里 this === global。ES2020 搞了个 globalThis 统一收口,省得你判断环境。
console.log(globalThis === window); // true(浏览器)
console.log(globalThis === global); // true(Node)
严格模式更干脆——全局 this 直接给 undefined,逼你写出更安全的代码。

对象方法调用
obj.fn() 叫隐式绑定。this 指向点号左边的东西,没有例外。
const user = {
name: 'Kimi',
greet() {
console.log(this.name);
}
};
user.greet(); // 'Kimi'
换种写法,结果完全不同:
const fn = user.greet;
fn(); // undefined —— this 丢了
函数不"属于"某个对象,它只是被借过去调用了。一旦脱离对象单独执行,this 就变回全局对象。这叫隐式丢失,面试常问。
多层嵌套
const user = {
name: 'Kimi',
profile: {
name: 'Profile',
get() {
return this.name;
}
}
};
user.profile.get(); // 'Profile'
this 只看直接调用者——点号左边最近的那个。user.profile.get() 里,get 的调用者是 profile,不是 user。

常见坑
赋值即丢失
const obj = {
name: 'test',
fn() {
console.log(this.name);
}
};
const fn = obj.fn;
fn(); // undefined
把方法存到变量里,调用方式从 obj.fn() 变成 fn(),this 就没了。
回调传递
const btn = {
text: 'Click me',
onClick() {
console.log(this.text);
}
};
setTimeout(btn.onClick, 100); // undefined
这里传的是函数引用,不是调用。btn.onClick 取到的是函数本身,上下文丢得一干二净。
怎么修
箭头函数
箭头函数没有自己的 this,它继承定义时所在作用域的 this。最适合做回调:
const obj = {
name: 'timer',
start() {
setTimeout(() => {
console.log(this.name); // 'timer'
}, 100);
}
};
start 里的箭头函数捕获了 start 的 this,所以 setTimeout 回调里还能拿到 name。
箭头函数只适合做回调。别在对象方法上用箭头函数定义——那拿不到对象本身。
call / apply / bind
三种显式指定 this 的方式:
function log() {
console.log(this.name);
}
const obj = { name: '手动指定' };
log.call(obj); // '手动指定'
log.apply(obj); // '手动指定'
const bound = log.bind(obj);
bound(); // '手动指定'
call 和 apply 区别只有一个:传参方式(逐个 vs 数组)。bind 返回新函数,this 永久绑定。
一句话
别问"这个函数里 this 是什么"——问它是怎么被调用的。
| 调用方式 | this 指向 |
|---|---|
| 全局直接调用 | 全局对象(严格模式 undefined) |
obj.method() | 点号左侧的对象 |
独立调用 fn() | 全局对象(严格模式 undefined) |
| 箭头函数 | 定义时的外部作用域 |
call/bind/apply | 手动指定的对象 |