JavaScript - this 关键字

你好,有抱负的JavaScript开发者们!今天,我们将踏上一段激动人心的旅程,探索 this 关键字的世界。作为你友好的计算机科学老师,我在这里引导你通过这个有时有点棘手,但总是引人入胜的概念。所以,拿起你最喜欢的饮料,舒服地坐下来,让我们一起深入探讨!

JavaScript - this Keyword

'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' 在函数中的严格模式

严格模式就像严格的老师,不让你逃脱任何东西。在严格模式下,函数中的 thisundefined,除非明确设置。

"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(最高)
显式绑定(callapplybind 2
方法调用 3
函数调用 4(最低)

记住,箭头函数是特殊的,总是从它们周围的作用域继承 this

那么,亲爱的朋友们!我们已经穿越了 this 的领域,探索了它的多面性和特性。记住,理解 this 就像学习骑自行车——一开始可能会摇晃,但经过练习,你很快就会飞驰。继续编码,继续探索,最重要的是,继续在JavaScript中享受乐趣!

Credits: Image by storyset