JavaScript 中的 this 值取决于函数调用方式而非定义方式:普通调用时非严格模式指向全局对象、严格模式为 undefined;箭头函数继承外层 this;方法调用时指向点号左侧对象;构造调用时指向新实例;call/apply/bind 可显式绑定 this。

JavaScript 中的 this 不指向函数本身,也不固定指向某个对象——它的值完全取决于函数「怎么被调用」,而不是「怎么被定义」。理解这点是避免常见 bug 的关键。
普通函数调用时,this 指向全局对象或 undefined
在非严格模式下,直接调用函数(如 foo()),this 指向全局对象(浏览器中是 window,Node.js 中是 global);严格模式下则为 undefined。
function foo() {
console.log(this);
}
foo(); // 非严格模式 → window;严格模式 → undefined
- 箭头函数没有自己的
this,它会沿作用域链向上找外层普通函数的this - 不要依赖非严格模式下的隐式绑定,容易在模块/类中意外访问到全局对象
- ES6 模块默认启用严格模式,所以模块顶层的普通函数调用中
this是undefined
方法调用时,this 指向调用它的对象
当函数作为对象的属性被调用(即 obj.method()),this 绑定到该对象。
const obj = {
name: 'Alice',
greet() {
console.log(`Hello, ${this.name}`);
}
};
obj.greet(); // Hello, Alice
- 只看调用时的「点左边是谁」:如果左边是
obj,this就是obj - 一旦把方法单独提取出来(如
const g = obj.greet;),再调用g()就变成普通调用,this失效 - 这种丢失常发生在事件监听、回调传参、定时器等场景,需用
.bind()、箭头函数或class字段语法(greet = () => { ... })修复
构造函数与 class 中,this 指向新创建的实例
用 new 调用函数时,引擎会自动创建空对象,并将 this 绑定到它;class 构造器内部的 this 同理。
立即学习“Java免费学习笔记(深入)”;
function Person(name) {
this.name = name; // this 指向 new 出来的实例
}
const p = new Person('Bob');
class Animal {
constructor(type) {
this.type = type; // this 指向 new Animal() 实例
}
}
-
class方法默认不绑定this,仍可能在回调中丢失(和普通对象方法一样) - 构造函数内若忘记写
new,会导致this指向全局或undefined,静默出错 - 可加保护逻辑:
if (!(this instanceof Person)) throw new Error('Use new')
显式绑定:call、apply、bind 改变 this 指向
这三个方法允许你手动指定函数执行时的 this 值。其中 bind 返回新函数,call 和 apply 立即执行。
function logInfo() {
console.log(this.id, this.msg);
}
const ctx = { id: 42, msg: 'ok' };
logInfo.call(ctx); // 42 'ok'
logInfo.apply(ctx); // 同上
const bound = logInfo.bind(ctx);
bound(); // 42 'ok'
-
call和apply参数区别:前者传逗号分隔参数,后者传数组 -
bind返回的函数无法再被new调用(除非是bind后又用new包裹的特殊构造) - 现代代码中更倾向用箭头函数或
class字段语法替代频繁bind,但底层原理仍依赖显式绑定
真正难的不是记住规则,而是识别「调用形式是否发生了隐式转换」——比如 array.forEach(obj.method) 中的 obj.method 已经脱离了 obj,this 会丢失。这类问题往往只在运行时暴露,调试时要盯住调用链最末端的那个点操作。










