JavaScript - this 关键字
你好,有抱负的JavaScript开发者们!今天,我们将踏上一段激动人心的旅程,探索 this
关键字的世界。作为你友好的计算机科学老师,我在这里引导你通过这个有时有点棘手,但总是引人入胜的概念。所以,拿起你最喜欢的饮料,舒服地坐下来,让我们一起深入探讨!
'this' 关键字是什么?
想象你在一个聚会上,有人大喊:“嘿,你!”谁会转过身来?每个人,对吧?但如果他们说:“嘿,Sarah!”只有Sarah会回应。在JavaScript中,this
关键字就像是对一个对象说“嘿,你!”。它是一种引用当前上下文中的对象的方式。
this
关键字是一个在每个函数的作用域中自动定义的特殊标识符。但这里有个陷阱——它的值取决于函数是如何被调用的。this
的这种动态性质正是它既强大又有时令人困惑的原因。
'this' 指的是哪个对象?
现在,事情变得有趣了。this
所引用的对象可以根据它如何以及在哪里使用而改变。这就像变色龙,根据周围环境改变颜色。让我们看看一些场景:
语法
在我们深入探讨之前,让我们快速了解一下我们如何使用 this
:
console.log(this);
简单,对吧?但不要被它的简单性所迷惑。当我们将其用于不同的上下文时,魔法(或恶作剧)就会发生。
JavaScript 中 'this' 在全局作用域
当在全局作用域(任何函数之外)使用时,this
指的是全局对象。在浏览器中,这通常是 window
对象。
console.log(this === window); // true
this.myGlobalVar = "我是全局的!";
console.log(window.myGlobalVar); // "我是全局的!"
在这里,this
就像VIP通行证,让你可以进入整个聚会(全局作用域)。
JavaScript 中 'this' 在函数中
当在普通函数中使用 this
时,它的值取决于函数是如何被调用的。
function showThis() {
console.log(this);
}
showThis(); // window(在非严格模式下)
在这种情况下,this
就像一只迷路的狗,附着在周围的任何东西上——在非严格模式下,这是全局对象。
'this' 在函数中的严格模式
严格模式就像严格的老师,不让你逃脱任何东西。在严格模式下,函数中的 this
是 undefined
,除非明确设置。
"use strict";
function strictThis() {
console.log(this);
}
strictThis(); // undefined
'this' 在构造函数中
当函数作为构造函数(使用 new
关键字)使用时,this
指向新创建的对象。
function Person(name) {
this.name = name;
this.greet = function() {
console.log("你好,我是 " + this.name);
};
}
const john = new Person("John");
john.greet(); // "你好,我是 John"
在这里,this
就像出生证明,确立新出生对象的身份。
'this' 在箭头函数中
箭头函数是JavaScript世界的叛逆者。它们不会绑定自己的 this
,而是从包围作用域继承。
const obj = {
name: "Alice",
sayHello: () => {
console.log("你好," + this.name);
}
};
obj.sayHello(); // "你好,undefined"
在这种情况下,箭头函数中的 this
不指向 obj
,而是指向周围的作用域(可能是全局作用域)。
'this' 在对象方法中
当在对象的方法(作为对象属性的函数)中使用 this
时,它指的是调用该方法的那个对象。
const car = {
brand: "Toyota",
getBrand: function() {
return this.brand;
}
};
console.log(car.getBrand()); // "Toyota"
在这里,this
就像忠诚的管家,总是指向它的主人(对象)。
'this' 在对象方法中的子函数
这里事情可能会变得棘手。在方法中的函数中,this
不再指向该对象。
const restaurant = {
name: "美味佳肴",
getMenu: function() {
function displayName() {
console.log(this.name);
}
displayName();
}
};
restaurant.getMenu(); // undefined
在这种情况下,displayName()
中的 this
指向全局对象,而不是 restaurant
。
JavaScript 中 'this' 在事件处理器中
在事件处理器中,this
通常指向接收事件的元素。
<button id="myButton">点击我!</button>
<script>
document.getElementById("myButton").addEventListener("click", function() {
console.log(this); // <button id="myButton">点击我!</button>
});
</script>
在这里,this
就像聚光灯,聚焦在表演的明星——被点击的元素上。
JavaScript 中的显式函数绑定
有时,我们想成为老板,告诉 this
它应该是什么。我们可以使用 call()
、apply()
或 bind()
来实现。
const person1 = { name: "Alice" };
const person2 = { name: "Bob" };
function sayHello() {
console.log("你好," + this.name);
}
sayHello.call(person1); // "你好,Alice"
sayHello.apply(person2); // "你好,Bob"
const boundHello = sayHello.bind(person1);
boundHello(); // "你好,Alice"
这些方法就像导演,告诉 this
它应该扮演的准确角色。
JavaScript 'this' 优先级
现在,让我们总结一下 this
绑定的优先级:
规则 | 优先级 |
---|---|
new 关键字 |
1(最高) |
显式绑定(call 、apply 、bind ) |
2 |
方法调用 | 3 |
函数调用 | 4(最低) |
记住,箭头函数是特殊的,总是从它们周围的作用域继承 this
。
那么,亲爱的朋友们!我们已经穿越了 this
的领域,探索了它的多面性和特性。记住,理解 this
就像学习骑自行车——一开始可能会摇晃,但经过练习,你很快就会飞驰。继续编码,继续探索,最重要的是,继续在JavaScript中享受乐趣!
Credits: Image by storyset