JS 中的 this 关键字
I’m happy to translate the article for you, but I’ll need the full text you’d like translated. Could you please paste the content (excluding the source line you already provided) here? Once I have the article, I’ll translate it into Simplified Chinese while preserving the original formatting, markdown, and code blocks.
介绍
this 关键字在 JavaScript 中常常让初级和高级开发者感到困惑。
理解 this 并不取决于函数定义的位置,而是取决于调用方式。
基本示例
let obj = {
name: "Kush",
displayName() {
console.log(`My name is ${this.name}`);
}
};
obj.displayName(); // My name is Kush如果方法从其对象中分离,绑定会改变:
let person = obj.displayName;
person(); // My name is undefined在非严格模式下,this 默认指向全局 window 对象(在浏览器中)。
在严格模式下,this 为 undefined。
箭头函数
箭头函数 没有 自己的 this;它们会从外围作用域词法捕获 this。
let obj = {
name: "Kush",
personName: () => {
console.log(`My name is ${this.name}`);
}
};
obj.personName(); // My name is undefined理解 this 与规则
JavaScript 有四条主要的绑定规则。适用哪条规则取决于 函数的调用方式。
1. 默认绑定
当普通函数在没有显式对象的情况下被调用时,this 遵循默认绑定规则。
function show() {
console.log(this);
}
show(); // 在浏览器中(非严格模式):Window 对象
// 在严格模式下:undefined2. 隐式绑定
当函数作为对象的方法被调用时,this 指向该对象。
const user = {
name: "Kush",
greet() {
console.log(this.name);
}
};
user.greet(); // Kush丢失隐式绑定
常见错误是失去对象引用:
const user = {
name: "Kush",
greet() {
console.log(this.name);
}
};
const greetFn = user.greet;
greetFn(); // undefined(应用默认绑定)3. 显式绑定(call、apply、bind)
可以使用 call、apply 或 bind 显式设置 this。
const user1 = { name: "Kush" };
const user2 = { name: "Rahul" };
function greet() {
console.log(this.name);
}
greet.call(user1); // Kush
greet.call(user2); // Rahul4. 箭头函数(词法绑定)
箭头函数从其词法(外层)作用域继承 this。
const user = {
name: "Kush",
greet: () => {
console.log(this.name);
}
};
user.greet(); // undefined(继承自全局作用域)正确使用箭头函数
箭头函数在 另一个方法内部 很有用,因为它们会捕获该方法的 this。
const user = {
name: "Kush",
greet() {
const say = () => {
console.log(this.name);
};
say();
}
};
user.greet(); // Kush常见的异步示例 (setTimeout)
问题:普通函数回调
const user = {
name: "Kush",
greet() {
setTimeout(function () {
console.log(this.name);
}, 1000);
}
};
user.greet(); // undefined (callback 的 `this` 是全局对象)解决方案:箭头函数回调
const user = {
name: "Kush",
greet() {
setTimeout(() => {
console.log(this.name);
}, 1000);
}
};
user.greet(); // Kush测验:预测输出
const user = { name: "Kush", greet() { setTimeout(function () { console.log(this.name); }, 0); } }; user.greet();const user = { name: "Kush", greet() { setTimeout(() => { console.log(this.name); }, 0); } }; user.greet();const user1 = { name: "Kush" }; const user2 = { name: "Rahul" }; function greet() { console.log(this.name); } greet.call(user1); greet.call(user2);const user = { name: "Kush" }; const greet = () => { console.log(this.name); }; greet.call(user);const user = { name: "Kush", address: { name: "Delhi", greet() { console.log(this.name); } } }; user.address.greet();const user1 = { name: "Kush", greet() { console.log(this.name); } }; const user2 = { name: "Rahul" }; user2.greet = user1.greet; user2.greet();const user = { name: "Kush", greet() { return function () { console.log(this.name); }; } }; user.greet()();
如果你能正确预测所有输出,你就走在正确的道路上!