理解 JavaScript 中的 this 关键字:终极指南
Source: Dev.to
Introduction
想象一下,你在派对上,有人喊道:“嘿,你!”——但他们在叫谁呢?这完全取决于他们面对的是谁。这正是 JavaScript 的 this 关键字的工作方式。它没有固定的身份;它会动态指向调用函数的对象。
掌握 this 对任何 JavaScript 开发者都至关重要,因为它决定了函数能够访问哪些数据。弄错了,代码会神秘地出错;弄对了,你就能释放面向对象 JavaScript 的全部威力。
this 实际代表什么?
在 JavaScript 中,this 指向当前正在执行代码的对象。可以把它看作 函数的调用者。它的值并不是在写代码时就确定的——它会根据函数 如何 以及 在何处 被调用而动态决定。
关键原则
- 执行环境(浏览器 vs. Node.js)
- 调用上下文(方法调用、普通函数调用等)
- 严格模式 vs. 非严格模式
this 在全局上下文中
在全局作用域中,this 指向全局对象。
// 浏览器环境
console.log(this); // → window 对象
// Node.js 环境
console.log(this); // → {}(空对象)
// 类型始终是 "object"
console.log(typeof this); // → "object"
总结: 在全局作用域中,this 等于当前环境的全局对象。
this 在对象内部(方法调用)
当函数作为对象的方法被调用时,this 指向该对象。
const person = {
name: "Ritam",
greet() {
console.log(`Hello, I'm ${this.name}!`);
}
};
person.greet(); // → "Hello, I'm Ritam!"
规则: 对于 obj.method(),this = obj。
this 在普通函数中的使用
非严格模式
function regularFunc() {
console.log(this);
}
regularFunc();
// Browser → window object
// Node.js → global object (or empty object)
严格模式
"use strict";
function strictFunc() {
console.log(this);
}
strictFunc(); // → undefined (both environments)
在普通函数中,this 取决于函数的调用方式。 在严格模式下,普通调用会返回 undefined。
Source: …
this 在箭头函数中
箭头函数 词法继承 this,即从其所在的外层作用域中获取 this。
// Node.js 环境
const arrowTest = () => console.log(this);
arrowTest(); // → {}(空对象)
// 浏览器环境
arrowTest(); // → window 对象
对象内部的嵌套函数
普通的嵌套函数会失去外层的 this:
const calculator = {
value: 100,
calculate() {
function innerFunc() {
console.log(this.value); // → undefined!
}
innerFunc();
}
};
calculator.calculate(); // undefined
解决方案: 将内部函数改为箭头函数,使其继承外层的 this。
const calculatorFixed = {
value: 100,
calculate() {
const innerFunc = () => {
console.log(this.value); // → 100
};
innerFunc();
}
};
calculatorFixed.calculate(); // 完美运行!
常见陷阱及解决方案
分离的方法调用
const user = {
name: "Ritam",
sayHello() {
console.log(`Hi from ${this.name}`);
}
};
// 方法调用 → this = user
user.sayHello(); // → "Hi from Ritam"
// 分离的函数调用 → this = global/undefined
const hello = user.sayHello;
hello(); // → "Hi from undefined"
当方法从其所属对象中抽离出来时,原本的 this 绑定会丢失。
解决办法
- 使用
bind永久设置this。 - 对需要外层
this的回调使用箭头函数。 - 在旧代码库中,可将外层上下文保存到变量中(
const self = this;)。
不同上下文中 this 的汇总表
| 上下文 | 浏览器(非严格模式) | Node.js(非严格模式) | 严格模式 |
|---|---|---|---|
| 全局 | window | {}(空对象) | undefined |
| 对象方法 | 对象本身 | 对象本身 | 对象本身 |
| 普通函数调用 | window | global / {} | undefined |
| 箭头函数 | 词法 this(继承) | 词法 this(继承) | 词法 this(继承) |
要点概览
- 思考“调用者”:
this等于调用函数的对象。 - 对象方法可靠:
obj.method()总是将this绑定到obj。 - 箭头函数继承: 在需要外层
this的回调和嵌套函数中非常适用。 - 避免在普通函数中依赖
this,除非你确信调用上下文。 - 旧式模式:
const self = this;可以在 ES6 之前的代码中保持上下文。
掌握 this 能让你从 JavaScript 使用者升华为 JavaScript 架构师。下次看到这个狡黠的关键字时,你就能准确知道它指向的是谁!