JS中【普通函数中的this】vs【箭头函数中的this】

在 JavaScript 中,this 关键字是一个非常重要的概念,它通常指向函数执行时的上下文对象。然而,箭头函数(arrow functions)中的 this 行为与普通函数不同,它的 this 是在函数定义时绑定的,并且无法通过调用方式或其他方式改变。下面将详细解释这一概念。

1. 普通函数中的 this

首先,了解普通函数中的 this 是如何工作的。

1.1 全局上下文中的 this

在全局执行环境(例如在浏览器中,直接在脚本或函数外部定义的函数),this 通常指向全局对象。在浏览器中,this 指向 window 对象。

function normalFunction() {console.log(this);
}normalFunction(); // 在浏览器中,输出 window 对象
1.2 对象方法中的 this

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

const obj = {name: 'Alice',greet: function() {console.log(this.name);}
};obj.greet(); // 输出: Alice

在这个例子中,greet 方法中的 this 指向 obj 对象。

1.3 构造函数中的 this

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

function Person(name) {this.name = name;
}const person1 = new Person('Alice');
console.log(person1.name); // 输出: Alice

在构造函数 Person 中,this 指向新创建的对象 person1

2. 箭头函数中的 this

与普通函数不同,箭头函数不会创建自己的 this 上下文。相反,箭头函数中的 this 是在定义时根据其外部词法环境绑定的,并且不会再改变。这种行为被称为“词法绑定”或“词法作用域中的 this”。

2.1 词法作用域中的 this

词法作用域意味着箭头函数中的 this 是由函数定义时所在的外层作用域决定的,而不是由函数如何调用决定的。

const obj = {name: 'Alice',greet: () => {console.log(this.name);}
};obj.greet(); // 输出: undefined

在上面的代码中,greet 是一个箭头函数。由于箭头函数不创建自己的 this,它继承自定义时的上下文。在这个例子中,greet 函数的 thisobj 定义时所在的外层作用域——全局作用域中的 this(在浏览器中为 window 对象)。而全局对象中并没有 name 属性,因此输出 undefined

2.2 在对象方法中使用箭头函数

因为箭头函数的 this 是在定义时确定的,所以当它们作为对象方法使用时,this 也不会指向对象本身。

const obj = {name: 'Alice',greet: function() {const arrowFunc = () => {console.log(this.name);};arrowFunc();}
};obj.greet(); // 输出: Alice

在这个例子中,arrowFunc 是一个箭头函数,它定义在 greet 方法内部。arrowFuncthis 是在 greet 函数定义时确定的,因此它继承了 greet 方法中的 this,即 obj 对象。所以,这里 arrowFunc 能够正确地访问 obj.name

2.3 在回调函数中使用箭头函数

箭头函数在回调函数中使用非常方便,因为它们避免了 this 丢失的常见问题。

const obj = {name: 'Alice',greet: function() {setTimeout(() => {console.log(this.name);}, 1000);}
};obj.greet(); // 一秒后输出: Alice

在上面的代码中,setTimeout 是在 greet 方法内调用的,回调函数使用了箭头函数。由于箭头函数的 this 是从 greet 方法继承的,因此在 setTimeout 触发后,this 仍然指向 obj 对象,而不是 window 对象。

3. this 的不可改变性

由于箭头函数的 this 是在定义时确定的,因此无法通过常见的方法(如 bindcallapply)来改变箭头函数的 this

const obj1 = {name: 'Alice',
};const obj2 = {name: 'Bob',
};const arrowFunc = () => {console.log(this.name);
};arrowFunc.call(obj1); // 输出: undefined
arrowFunc.apply(obj2); // 输出: undefined

在这个例子中,尽管我们使用了 callapply 方法试图改变 arrowFunc 中的 this,但结果都是 undefined。这是因为 arrowFuncthis 是在定义时就绑定的,并且无法再改变。

4. 注意事项与最佳实践

  • 避免在需要动态 this 的场景中使用箭头函数:由于箭头函数的 this 是固定的,因此在需要动态绑定 this 的场景中(例如事件处理函数、回调函数中)要慎重使用。

  • 使用箭头函数处理回调问题:箭头函数在回调函数中非常有用,尤其是当回调函数嵌套在对象方法中时,能够避免 this 丢失的问题。

  • 在类的方法中慎用箭头函数:在 JavaScript 类的实例方法中使用箭头函数时需要小心,因为这可能导致 this 无法正确绑定到实例对象。

5. 总结

箭头函数中的 this 是在定义时确定的,并且会继承自外层词法作用域,而不是像普通函数那样在调用时确定。这个特性使得箭头函数在某些场景下非常有用,尤其是在处理回调函数时。然而,由于 this 的不可改变性,也需要注意避免在需要动态上下文的场景中使用箭头函数。了解并掌握箭头函数中 this 的行为能够帮助你写出更简洁、更健壮的 JavaScript 代码。

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/pingmian/53069.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

day35-测试之性能测试JMeter的测试报告、并发数计算和性能监控

目录 一、JMeter的测试报告 1.1.聚合报告 1.2.html报告 二、JMeter的并发数计算 2.1.性能测试时的TPS,大都是根据用户真实的业务数据(运营数据)来计算的 2.2.运营数据 2.3.普通计算方法 2.4.二八原则计算方法 2.5.计算稳定性测试并发量 2.6…

【数学建模】国赛论文模型的建立与求解写作指南

一、内容含义 1、模型的建立 模型的建立是将问题抽象成数学语言的表达式,它一定是在先前的问题分析和模型假设的基础上得来的。因为比赛时间很紧,大多数时候我们都是使用别人已经建立好的模型。这一部分需要将题目问的问题和模型紧密结合起来切记随意套…

Mybatis链路分析:JDK动态代理和责任链模式的应用

背景 此前写过关于代理模式的文章,参考:代理模式 动态代理功能:生成一个Proxy代理类,Proxy代理类实现了业务接口,而通过调用Proxy代理类实现的业务接口,实际上会触发代理类的invoke增强处理方法。 责任链功…

Mac 安装Hadoop教程(HomeBrew安装)

1. 引言 本教程旨在介绍在Mac 电脑上安装Hadoop,便于编程开发人员对大数据技术的熟悉和掌握。 2.前提条件 2.1 安装JDK 想要在你的Mac电脑上安装Hadoop,你必须首先安装JDK。具体安装步骤这里就不详细描述了。你可参考Mac 安装JDK8。 2.2 配置ssh环境…

【conda】导出和重建 Conda 环境

目录 1. 导出 Conda 环境1.1 激活环境1.2 导出环境配置1.3 检查和编辑环境配置文件(可选)1.4 共享或重建环境 2. 常见问题及解决方案2.1 导出环境时出现 “PackagesNotFoundError”2.2 导出的 environment.yml 文件在其他系统上无法使用2.3 导出的环境文…

【时时三省】c语言例题----华为机试题<求最大连续bit数>。

目录 1,题目 描述 输入描述: 输出描述: 示例1 2,代码 3,官方案例 山不在高,有仙则名。水不在深,有龙则灵。 ----CSDN 时时三省 1,题目 HJ86 求最大连续bit数 描述 求一个int类型数字对应的二进制数字中1的最大连续数,例如3的二进制为00000011,最大连续2个…

Docker入门学习-01

Docker 官方文档 1. Docker 基础知识 1.1 什么是 Docker? Docker 是一个开源的平台,用于开发、交付和运行应用程序。它使用容器技术,将应用程序及其依赖打包在一个轻量级的可移植容器中。 1.2 Docker 的主要组件 镜像(Image&a…

【计算机视觉前沿研究 热点 顶会】ECCV 2024中目标检测有关的论文

整值训练和尖峰驱动推理尖峰神经网络用于高性能和节能的目标检测 与人工神经网络(ANN)相比,脑激励的脉冲神经网络(SNN)具有生物合理性和低功耗的优势。由于 SNN 的性能较差,目前的应用仅限于简单的分类任务。在这项工作中,我们专注于弥合人工…

【CVPR‘24】DeCoTR:使用 2D 和 3D 注意力增强深度补全

DeCoTR: Enhancing Depth Completion with 2D and 3D Attentions DeCoTR: Enhancing Depth Completion with 2D and 3D Attentions 中文解析摘要介绍方法方法3.1 问题设置3.2 使用高效的 2D 注意力增强基线3.3 3D中的特征交叉注意力点云归一化位置嵌入3.4 捕捉 3D 中的全局上下…

分享GoFly项目案例-降本增效数字化解决多仓库、动态仓库(车辆存储)、动态调调度、动态配送方案

前言 传统的生产原料企业在数字化转型中,需要到一个客户与产品配送(运输)管理及调度系统。系统要达到管理者可以看到产品数据,做业务的可以了解到货品库存、货品位置(可调度最近货品给客户)、货品配送情况…

给鼠标一个好看的指针特效 鼠标光标如何修改形状?

许多爱美的小伙伴们都想着如何给自己的电脑打扮一下,用各种各样的途径来美化我们的电脑。今天我们给大家分享一下,如何美化鼠标效果,给鼠标指针修改成一个非常好看的形状~ 一起来看几组鼠标的效果,小编我给大家做了个录屏&#x…

linux文件——用户缓冲区——概念深度探索、IO模拟实现

前言:本篇文章主要讲解文件缓冲区。 讲解的方式是通过抛出问题, 然后通过分析问题, 将缓冲区的概念与原理一步一步地讲解。同时, 本节内容在最后一部分还会带友友们模拟实现一下c语言的printf, fprintf接口&#xff0c…

OT安全零死角!Fortinet OT安全平台再升级

近日,专注推动网络与安全融合的全球网络安全领导者 Fortinet(NASDAQ:FTNT),宣布对旗下业界领先的OT安全平台进行新一轮全面升级,此次更新旨在深化安全组网与安全运营(SecOps)服务的功…

依托自研力量,给共享集群存储服务一个优选

YashanDB共享集群有三大关键组件,崖山集群服务(YCS)、崖山集群文件系统(YFS)、DB组件。上一篇共享集群系列文章《为何共享集群的高可用能力被频频称赞,它的机制有何不同?》深入解析了关键组件的…

NVIDIA RTX 50系列大爆料:功耗飙升600W,性能直逼RTX 4090 1.?倍,你准备好了吗?

在科技圈的万众瞩目下,知名硬件爆料大神Kopite7kimi再次为我们揭开了NVIDIA下一代GeForce RTX系列——“Blackwell”阵容的神秘面纱。这次,关于新显卡的功耗信息不再是模糊的概念,而是实实在在的数字,让人不禁对即将到来的性能飞跃…

ELK学习笔记(一)——使用K8S部署ElasticSearch8.15.0集群

一、下载镜像 #1、下载官方镜像 docker pull elasticsearch:8.15.0 #2、打新tag docker tag elasticsearch:8.15.0 192.168.9.41:8088/new-erp-common/elasticsearch:8.15.0 #3、推送到私有仓库harbor docker push 192.168.9.41:8088/new-erp-common/elasticsearch:8.15.0二、…

Python3.8绿色便携版安装版制作

Python 的绿色便携版有两种:官方 Embeddable 版本(嵌入式版);安装版制作的绿色版。Embeddable 版适用于需要将 Python 集成到其他应用程序或项目中的情况,它不包含图形界面的安装程序,只提供了 Python 解释器和必要的库…

C# 使用国密SM4加密解密

首先需第三方Nuget包:Portable.BouncyCastle (源码来自http://www.bouncycastle.org/csharp/),支持.NET 4,.NET Standard 2.0 目录 目录 使用BouncyCastle指定填充方案 零填充(Zero Padding) PKCS7填充…

排查SQL Server中的内存不足及其他疑难问题

文章目录 引言I DMV 资源信号灯资源信号灯 DMV sys.dm_exec_query_resource_semaphores( 确定查询执行内存的等待)查询性能计数器什么是内存授予?II DBCC MEMORYSTATUS 查询内存对象III DBCC 命令释放多个 SQL Server 内存缓存 - 临时度量值IV 等待资源池 %ls (%ld)中的内存…

Matlab R2022b使用Camera Calibrator工具箱张正友标定法进行相机标定附带标定前后对比代码

打开Camera Calibrator 在这添加你拍摄的图片 根据你每个方块的实际边长填写,我是15mm。 通俗一点,要k3就选3 Coefficients,否则为0;要p1、p2就选Tangential Distortion。然后进行计算。 可以点击右侧误差高的选中图像进行移…