普通函数直接调用时,非严格模式下this指向全局对象(浏览器为window,Node为global),严格模式下为undefined;箭头函数无自身this,继承定义时词法作用域的this值,且不可被call/apply/bind修改。

普通函数调用时 this 指向什么?
直接调用 fn(),非严格模式下 this 指向全局对象(浏览器中是 window,Node.js 中是 global);严格模式下为 undefined。这是最容易出错的场景——你以为在对象方法里写了个函数,结果单独拎出来调用,this 就丢了。
- 对象方法内定义的普通函数(非箭头),
this不继承外层对象,仍按调用方式决定 - 事件回调、定时器回调、异步回调(如
setTimeout)里直接写fn(),this也默认丢失 - 避免写
obj.method(); fn();然后指望fn里的this是obj—— 它不是
箭头函数的 this 是怎么确定的?
箭头函数没有自己的 this,它沿用定义时所在词法作用域的 this 值,且无法被 call/apply/bind 改写。这使得它特别适合用在回调中保持上下文。
const obj = {
name: 'alice',
regular() {
console.log(this.name); // 'alice'
setTimeout(function() {
console.log(this.name); // undefined(非严格)或报错(严格)
}, 100);
setTimeout(() => {
console.log(this.name); // 'alice',继承外层 regular 的 this
}, 100);
}
};
- 箭头函数不能用作构造函数(
new会报错) - 没有
arguments对象,要用剩余参数...args - 不能用
yield,不支持生成器语法
如何用 call/apply/bind 显式绑定 this?
三者都用于手动指定函数执行时的 this 值,区别只在参数传入方式:call 用逗号分隔,apply 用数组,bind 返回新函数(不立即执行)。
function greet(greeting, punctuation) {
return `${greeting}, ${this.name}${punctuation}`;
}
const person = { name: 'bob' };
greet.call(person, 'Hello', '!'); // "Hello, bob!"
greet.apply(person, ['Hi', '?']); // "Hi, bob?"
const boundGreet = greet.bind(person, 'Hey');
boundGreet('.'); // "Hey, bob."
-
bind常用于预设部分参数(柯里化),也常用来修复事件处理器中的this -
call和apply多用于借用方法,比如Array.prototype.slice.call(arguments) - 注意:箭头函数对这三者完全免疫,调用无效
class 方法里的 this 为什么经常 undefined?
类中定义的方法默认是“普通函数”,如果从对象上取出来单独调用(如传给事件监听器、定时器、Promise 回调),this 就会丢失。这不是 class 特性问题,而是函数调用规则本身导致的。
立即学习“Java免费学习笔记(深入)”;
class Button {
constructor() {
this.label = 'click me';
}
handleClick() {
console.log(this.label); // 若直接 onclick="handleClick()" 或作为回调传入,这里会是 undefined
}
init() {
// ❌ 错误:this.handleClick 被提取后失去绑定
document.addEventListener('click', this.handleClick);
// ✅ 正确:用 bind / 箭头函数 / 包装函数
document.addEventListener('click', this.handleClick.bind(this));
// 或
document.addEventListener('click', () => this.handleClick());
// 或
document.addEventListener('click', (e) => this.handleClick(e));
}
}
- 类字段语法 + 箭头函数写法(
handleClick = () => {})可自动绑定,但每次实例化都会创建新函数,有内存开销 - React 类组件中常见该问题,函数组件配合
useCallback是更现代的解法 - 不要依赖编译器(如 Babel)自动插
bind,明确写出绑定逻辑才可控
undefined 或指向错误对象——查起来比语法错误还费时间。











