JavaScript 中 `this` 指向的深度剖析

🤍 前端开发工程师、技术日更博主、已过CET6
🍨 阿珊和她的猫_CSDN博客专家、23年度博客之星前端领域TOP1
🕠 牛客高级专题作者、打造专栏《前端面试必备》 、《2024面试高频手撕题》、《前端求职突破计划》
🍚 蓝桥云课签约作者、上架课程《Vue.js 和 Egg.js 开发企业级健康管理项目》、《带你从入门到实战全面掌握 uni-app》
文章目录
引言
在 JavaScript 里,this 是一个特殊的关键字,它的指向是动态且灵活的,依据不同的使用场景会有不同的指向。深入理解 this 的指向机制,对于编写高效、稳定且易于维护的 JavaScript 代码至关重要。本文将深入探讨 this 在不同场景下的指向规则。
全局作用域中的 this
在全局作用域(也就是在任何函数外部)使用 this 时,它指向的是全局对象。在浏览器环境中,全局对象是 window 对象;而在 Node.js 环境里,全局对象是 global 对象。
// 浏览器环境
console.log(this === window); // true
// 定义一个全局变量
var globalVar = 'I am a global variable';
console.log(this.globalVar); // 'I am a global variable'
在上述代码中,this 指向全局对象 window,所以 this 可以访问到全局变量。
函数内部的 this
普通函数调用
当函数作为普通函数调用时,this 指向全局对象。不过,在严格模式下,this 的值为 undefined。
// 非严格模式
function normalFunction() {
console.log(this); // 浏览器环境中指向 window
}
normalFunction();
// 严格模式
function strictFunction() {
'use strict';
console.log(this); // undefined
}
strictFunction();
方法调用
若函数作为对象的方法调用,this 指向调用该方法的对象。
const person = {
name: 'John',
sayHello: function() {
console.log(`Hello, my name is ${this.name}`);
}
};
person.sayHello(); // 'Hello, my name is John'
在这个例子中,sayHello 方法中的 this 指向 person 对象,所以能够访问 person 对象的 name 属性。
构造函数调用
当函数作为构造函数调用(使用 new 关键字)时,this 指向新创建的对象。
function Person(name) {
this.name = name;
this.sayHello = function() {
console.log(`Hello, my name is ${this.name}`);
};
}
const newPerson = new Person('Jane');
newPerson.sayHello(); // 'Hello, my name is Jane'
这里,new Person('Jane') 创建了一个新的 Person 对象,构造函数中的 this 就指向这个新对象。
箭头函数中的 this
箭头函数不会创建自己的 this,它的 this 值继承自外层函数。
const obj = {
name: 'ArrowObj',
sayName: function() {
const arrowFunction = () => {
console.log(this.name);
};
arrowFunction();
}
};
obj.sayName(); // 'ArrowObj'
在上述代码中,箭头函数 arrowFunction 的 this 继承自 sayName 方法的 this,也就是 obj 对象。
改变 this 指向的方法
call() 方法
call() 方法允许你指定函数调用时 this 的值,并且可以传递参数。
function greet(message) {
console.log(`${message}, my name is ${this.name}`);
}
const person1 = { name: 'Alice' };
greet.call(person1, 'Hi'); // 'Hi, my name is Alice'
apply() 方法
apply() 方法和 call() 方法类似,区别在于 apply() 接收一个数组作为参数。
function greet(message) {
console.log(`${message}, my name is ${this.name}`);
}
const person2 = { name: 'Bob' };
greet.apply(person2, ['Hello']); // 'Hello, my name is Bob'
bind() 方法
bind() 方法会创建一个新的函数,在调用时 this 值会被绑定到指定的对象上。
function greet(message) {
console.log(`${message}, my name is ${this.name}`);
}
const person3 = { name: 'Charlie' };
const boundGreet = greet.bind(person3);
boundGreet('Hey'); // 'Hey, my name is Charlie'
事件处理函数中的 this
在事件处理函数中,this 通常指向触发事件的元素。
<!DOCTYPE html>
<html lang="en">
<body>
<button id="myButton">Click me</button>
<script>
const button = document.getElementById('myButton');
button.addEventListener('click', function() {
console.log(this); // 指向按钮元素
});
</script>
</body>
</html>
在这个例子中,点击按钮时,事件处理函数中的 this 指向按钮元素。
总结
JavaScript 中 this 的指向是一个复杂且关键的概念,它依据不同的使用场景会有不同的指向。在全局作用域中,this 指向全局对象;普通函数调用时,this 指向全局对象(严格模式下为 undefined);方法调用时,this 指向调用该方法的对象;构造函数调用时,this 指向新创建的对象;箭头函数的 this 继承自外层函数。此外,还可以使用 call()、apply() 和 bind() 方法来改变 this 的指向。在事件处理函数中,this 通常指向触发事件的元素。只有深入理解并熟练运用这些规则,才能在编写 JavaScript 代码时准确把握 this 的指向,避免出现意外的错误。
更多推荐

所有评论(0)