深入理解 JavaScript 中的 this 指向

devtools/2025/2/28 4:37:31/

前言

正值春招火热招聘阶段,我近期在复习JavaScript的相关知识点,其中“this”知识点是前端面试中高频面试内容,因此整理和总结一篇相关知识点文章和大家分享!

 在 JavaScript 中,this 是一个非常重要的关键字,它在函数和对象操作中扮演着关键角色。然而,this 的指向规则并不总是直观的,这让很多初学者感到困惑。本文将通过通俗易懂的方式,结合实际代码示例,帮助你彻底理解 this 的指向规则。

一、this的指向规则

this 的指向取决于函数的调用方式,而不是函数的定义方式。虽然“谁调用它,this 就指向谁”这种说法有一定道理,但并不完全准确。以下是 this 指向的几种常见情况:

1. 全局环境中的this

在全局环境下调用函数时,this 的指向会根据是否开启严格模式而有所不同。

  • 非严格模式this 指向全局对象(浏览器中是 window,Node.js 中是 global)。

  • 严格模式this 指向 undefined

javascript">function f1() {console.log(this);
}
​
function f2() {'use strict';console.log(this);
}
​
f1(); // 非严格模式:window 或 global
f2(); // 严格模式:undefined

2. 使用 new 调用构造函数

当使用 new 关键字调用函数时,this 会被绑定到新创建的对象上。

javascript">function Person(name) {this.name = name;
}
​
const person = new Person('Alice');
console.log(person.name); // 输出:Alice
console.log(person); // 输出:{ name: 'Alice' }

在这个例子中,this 指向了通过 new 创建的 person 对象。

3. 使用 call、apply、bind 显式绑定 this

callapplybind 是 JavaScript 中用来显式改变函数内部 this 指向的方法。

  • callapply:立即执行函数,并将 this 绑定到指定对象。callapply 的区别在于参数的传递方式:call 接收多个参数,apply 接收一个数组作为参数。
javascript">const obj = { name: 'Bob' };
​
function greet() {console.log(`Hello, ${this.name}!`);
}
​
greet.call(obj); // 输出:Hello, Bob!
greet.apply(obj); // 输出:Hello, Bob!
  • bind:返回一个新函数,该函数的 this 指向被永久绑定到指定对象。
javascript">const greetBob = greet.bind(obj);
greetBob(); // 输出:Hello, Bob!

4. 通过上下文对象调用函数

当通过对象的方法调用函数时,this 指向该对象。

javascript">const student = {name: 'Alice',greet: function() {console.log(`Hello, ${this.name}!`);}
};
​
student.greet(); // 输出:Hello, Alice!

如果函数被赋值给其他变量后调用,this 的指向会丢失,恢复到全局对象。

javascript">const greet = student.greet;
greet(); // 输出:Hello, undefined!

5. 箭头函数中的this

箭头函数是 ES6 引入的一种简化语法,它的 this 指向在定义时就已经确定,始终指向外层作用域的 this。

javascript">const obj = {name: 'Alice',greet: () => {console.log(`Hello, ${this.name}!`);}
};
​
obj.greet(); // 输出:Hello, undefined!

在这个例子中,箭头函数的 this 指向全局对象,而不是obj。

二、更复杂的场景

1、事件处理中的 this

在 DOM 事件处理中,事件处理函数的 this 指向绑定事件的元素。

javascript">document.getElementById('button').addEventListener('click', function() {console.log(this); // 指向绑定事件的按钮元素
});

如果事件处理函数是一个箭头函数, this 的指向会继承自外层作用域。

javascript">const button = document.getElementById('button');
button.addEventListener('click', () => {console.log(this); // 指向全局对象(浏览器中是 window)
});

2、嵌套函数中的 this

在嵌套函数中,this 的指向可能会变得复杂。普通函数的 this 指向取决于调用方式,而箭头函数的this 指向则继承自外层作用域。

javascript">const obj = {name: 'Alice',greet: function() {const inner = () => {console.log(`Hello, ${this.name}!`);};inner();}
};
​
obj.greet(); // 输出:Hello, Alice!

在这个例子中,箭头函数 inner 的 this 继承自外层的 greet 函数的 this,指向 obj

三、总结

this 的指向规则虽然复杂,但只要掌握以下要点,就可以轻松应对:

  1. 全局环境:非严格模式下指向全局对象,严格模式下指向 undefined

  2. 构造函数:使用 new 时,this 指向新创建的对象。

  3. 显式绑定:通过 callapplybind 可以显式改变 this 的指向。

  4. 上下文对象:通过对象调用函数时,this 指向该对象。

  5. 箭头函数this 指向外层作用域。


http://www.ppmy.cn/devtools/163253.html

相关文章

关于vue中el-date-picker type=daterange日期不回显的问题

在构建现代化的前端应用时,使用Element UI框架的el-date-picker组件可以帮助我们快速实现日期选择功能。然而,在处理日期范围选择(daterange)时,可能会遇到日期数据从后端获取并试图回显到前端界面时出现的问题。 一、…

【无人集群系列---无人机集群编队算法】

【无人集群系列---无人机集群编队算法】 一、核心目标二、主流编队控制方法1. 领航-跟随法(Leader-Follower)2. 虚拟结构法(Virtual Structure)3. 行为法(Behavior-Based)4. 人工势场法(Artific…

Linux主机用户登陆安全配置

Linux主机用户登陆安全配置 在Linux主机上进行用户登录安全配置是一个重要的安全措施,可以防止未经授权的访问。以下是如何创建用户hbu、赋予其sudo权限,以及禁止root用户SSH登录,以及通过ssh key管理主机用户登陆。 创建用户hbu 使用具有…

「宇树科技」13家核心零部件供应商梳理!

2025年2月6日,摩根士丹利(Morgan Stanley)发布最新人形机器人研报:Humanoid 100: Mapping the Humanoid Robot Value Chain(人形机器人100:全球人形机器人产业链梳理)。 Humanoid 100清单清单中…

计算机毕业设计 ——jspssm508Springboot 的旅游管理

作者:程序媛9688 开发技术:SpringBoot、SSM、Vue、MySQL、JSP、ElementUI、Python、小程序等。 🌟文末获取源码数据库🌟 感兴趣的可以先收藏起来,还有大家在毕设选题(免费咨询指导选题)&#xf…

车规级MCU与普通嵌入式芯片的区别

1 前言 本文主要以刹车控制系统中的微控制器(MCU)和家用扫地机器人电机控制为例进行对比说明车规级芯片与普通嵌入式芯片在功能安全等级上的区别。 2 车规级芯片(ASIL-D级) 应用场景:控制电动助力刹车(EH…

Ranorex 截图功能对UI测试有哪些优势

Ranorex 的截图功能在 UI 测试中具有显著的优势,尤其是在提高测试效率、增强测试报告的可读性以及优化测试执行过程方面。以下是具体的优势分析: 1. 提高测试效率 Ranorex 的截图功能可以自动化地在测试执行过程中捕获屏幕截图,并将其嵌入到…

基本网络安全的实现

基本网络安全的实现 一 :AAA AAA 是Authentication,Authorization and Accounting(认证、授权和计费)的简 称,它提供了一个用来对认证、授权和计费这三种安全功能进行配置的一致性框架, 它是对网络安全…