JavaScript中this关键字的工作原理及使用场景

JavaScript中this关键字的工作原理及使用场景

技术背景

在JavaScript里,this关键字是一个比较难理解的概念,其行为与其他语言有所不同。在面向对象语言中,this通常指向类的当前实例;而在JavaScript里,this的值由函数的调用上下文(context.function())和调用位置决定。这一特性导致在不同的调用场景下,this会指向不同的对象,从而给开发者带来理解上的困扰。

实现步骤

全局执行上下文

在全局作用域中使用this,它会指向全局对象。在浏览器环境下,全局对象是window;在Node.js环境下,全局对象是global

1
2
3
4
// 浏览器环境
console.log(this === window); // true
// Node.js环境
console.log(this === global); // true

若在全局作用域中定义的函数里使用this,它同样指向全局对象,因为该函数实际上成为了全局对象的方法。

1
2
3
4
function f1() {
return this;
}
console.log(f1() === window); // 在浏览器环境下输出true

对象方法内部

当在对象的方法里使用this时,this会指向调用该方法的对象。

1
2
3
4
5
6
7
var obj = {
name: "obj",
f: function () {
return this + ":" + this.name;
}
};
console.log(obj.f()); // [object Object]:obj

构造函数内部

当函数作为构造函数使用(即使用new关键字调用)时,this会指向新创建的对象。

1
2
3
4
5
function SimpleFun() {
this.myname = "simple function";
}
var obj1 = new SimpleFun();
console.log(obj1.myname); // simple function

函数的callapplybind方法

这三个方法能够改变函数调用时this的值。

1
2
3
4
5
6
7
8
function add(inc1, inc2) {
return this.a + inc1 + inc2;
}
var o = { a: 4 };
console.log(add.call(o, 5, 6)); // 15
console.log(add.apply(o, [5, 6])); // 15
var g = add.bind(o, 5, 6);
console.log(g()); // 15

箭头函数内部

箭头函数不会绑定自己的this,它会继承外层函数或全局作用域的this值。

1
2
3
4
const globalArrowFunction = () => {
return this;
};
console.log(globalArrowFunction()); // 在浏览器环境下输出window

事件处理函数内部

当直接将函数赋值给元素的事件处理程序时,事件处理函数里的this会指向对应的元素。

1
2
3
document.getElementById("button1").addEventListener("click", function () {
console.log(this); // 指向button1元素
});

核心代码

全局上下文示例

1
2
3
4
5
console.log(this); // 在浏览器环境下输出[object Window]
function globalFunction() {
console.log(this); // 在浏览器环境下输出[object Window]
}
globalFunction();

对象方法示例

1
2
3
4
5
6
7
var obj = {
name: "example",
method: function () {
return this.name;
}
};
console.log(obj.method()); // example

构造函数示例

1
2
3
4
5
function Person(name) {
this.name = name;
}
var person = new Person("John");
console.log(person.name); // John

callapplybind示例

1
2
3
4
5
6
7
8
function greet(message) {
console.log(message + ", " + this.name);
}
var obj = { name: "Alice" };
greet.call(obj, "Hello"); // Hello, Alice
greet.apply(obj, ["Hi"]); // Hi, Alice
var boundGreet = greet.bind(obj);
boundGreet("Bonjour"); // Bonjour, Alice

箭头函数示例

1
2
3
4
const arrowFunction = () => {
console.log(this);
};
arrowFunction(); // 在全局作用域下指向全局对象

事件处理函数示例

1
2
3
4
5
6
<button id="myButton">Click me</button>
<script>
document.getElementById("myButton").addEventListener("click", function () {
console.log(this); // 指向button元素
});
</script>

最佳实践

避免混淆this的指向

  • 当需要在嵌套函数中使用外层函数的this时,可以将this赋值给一个变量(如thatself)。
1
2
3
4
5
6
7
8
9
var obj = {
method: function () {
var that = this;
setTimeout(function () {
console.log(that); // 指向obj
}, 1000);
}
};
obj.method();

合理使用箭头函数

在需要继承外层this值的场景下,优先使用箭头函数。

1
2
3
4
5
6
7
8
9
10
var obj = {
name: "Example",
method: function () {
return () => {
console.log(this.name); // 指向obj
};
}
};
var innerFunction = obj.method();
innerFunction(); // Example

使用callapplybind来明确this的指向

在需要动态改变this指向的场景下,使用callapplybind方法。

1
2
3
4
5
6
7
8
9
function printName() {
console.log(this.name);
}
var person1 = { name: "Bob" };
var person2 = { name: "Charlie" };
printName.call(person1); // Bob
printName.apply(person2); // Charlie
var boundPrintName = printName.bind(person1);
boundPrintName(); // Bob

常见问题

this指向不符合预期

在一些复杂的场景下,如函数作为回调函数传递、方法赋值给变量等,this的指向可能会不符合预期。解决方法是使用callapplybind方法或者箭头函数来明确this的指向。

1
2
3
4
5
6
7
8
9
10
var obj = {
method: function () {
console.log(this);
}
};
var func = obj.method;
func(); // 此时this指向全局对象
// 使用bind方法解决
var boundFunc = obj.method.bind(obj);
boundFunc(); // 此时this指向obj

箭头函数与普通函数中this的差异

箭头函数不会绑定自己的this,它会继承外层的this值;而普通函数的this指向由调用方式决定。因此,在需要动态改变this指向的场景下,不能使用箭头函数。

1
2
3
4
5
6
7
8
9
10
11
var obj = {
name: "Example",
arrowMethod: () => {
console.log(this.name); // 这里的this指向全局对象
},
normalMethod: function () {
console.log(this.name); // 这里的this指向obj
}
};
obj.arrowMethod(); // 输出为空或undefined
obj.normalMethod(); // Example

严格模式下this的变化

在严格模式下,全局作用域和未绑定对象的匿名函数中的this值为undefined,而不是全局对象。

1
2
3
4
5
"use strict";
function strictFunction() {
console.log(this); // undefined
}
strictFunction();

JavaScript中this关键字的工作原理及使用场景
https://119291.xyz/posts/javascript-this-keyword-explanation/
作者
ww
发布于
2025年6月20日
许可协议