深入理解箭头函数,学习其非常特殊且有用的特性

简介: 深入理解箭头函数,学习其非常特殊且有用的特性

640.png

深入理解箭头函数


让我们深入研究一下箭头函数。


箭头函数不仅仅是编写简洁代码的“捷径”。它还具有非常特殊且有用的特性。

JavaScript 充满了我们需要编写在其他地方执行的小函数的情况。

例如:


  • arr.forEach(func) —— forEach 对每个数组元素都执行 func
  • setTimeout(func) —— func 由内建调度器执行。
  • ……还有更多。


JavaScript 的精髓在于创建一个函数并将其传递到某个地方。

在这样的函数中,我们通常不想离开当前上下文。这就是箭头函数的主战场啦。


箭头函数没有 "this"


正如我们在 [对象方法,"this"](https://zh.javascript.info/object-methods "对象方法,"this"") 一章中所学到的,箭头函数没有 this。如果访问 this,则会从外部获取。


例如,我们可以使用它在对象方法内部进行迭代:


let group = {
  title: "Our Group",
  students: ["John", "Pete", "Alice"],
  showList() {
    this.students.forEach(
      student => alert(this.title + ': ' + student)
    );
  }
};
group.showList();


这里 forEach 中使用了箭头函数,所以其中的 this.title 其实和外部方法 showList 的完全一样。那就是:group.title


如果我们使用正常的函数,则会出现错误:


let group = {
  title: "Our Group",
  students: ["John", "Pete", "Alice"],
  showList() {
    this.students.forEach(function(student) {
      // Error: Cannot read property 'title' of undefined
      alert(this.title + ': ' + student)
    });
  }
};
group.showList();


报错是因为 forEach 运行它里面的这个函数,但是这个函数的 this 为默认值 this=undefined,因此就出现了尝试访问 undefined.title 的情况。

但箭头函数就没事,因为它们没有 this


不能对箭头函数进行 new 操作

不具有 this 自然也就意味着另一个限制:箭头函数不能用作构造器(constructor)。不能用 new 调用它们。

箭头函数 VS bind

箭头函数 => 和使用 .bind(this) 调用的常规函数之间有细微的差别:

  • .bind(this) 创建了一个该函数的“绑定版本”。
  • 箭头函数 => 没有创建任何绑定。箭头函数只是没有 thisthis 的查找与常规变量的搜索方式完全相同:在外部词法环境中查找。


箭头函数没有 "arguments"


箭头函数也没有 arguments 变量。


当我们需要使用当前的 thisarguments 转发一个调用时,这对装饰器(decorators)来说非常有用。


例如,defer(f, ms) 获得了一个函数,并返回一个包装器,该包装器将调用延迟 ms 毫秒:


function defer(f, ms) {
  return function() {
    setTimeout(() => f.apply(this, arguments), ms)
  };
}
function sayHi(who) {
  alert('Hello, ' + who);
}
let sayHiDeferred = defer(sayHi, 2000);
sayHiDeferred("John"); // 2 秒后显示:Hello, John


不用箭头函数的话,可以这么写:


function defer(f, ms) {
  return function(...args) {
    let ctx = this;
    setTimeout(function() {
      return f.apply(ctx, args);
    }, ms);
  };
}


在这里,我们必须创建额外的变量 argsctx,以便 setTimeout 内部的函数可以获取它们。


总结


箭头函数:


  • 没有 this
  • 没有 arguments
  • 不能使用 new 进行调用
  • 它们也没有 super,但目前我们还没有学到它。我们将在 类继承[1] 一章中学习它。


这是因为,箭头函数是针对那些没有自己的“上下文”,但在当前上下文中起作用的短代码的。并且箭头函数确实在这种使用场景中大放异彩。

目录
相关文章
|
安全 Linux Shell
【内网安全-CS】Cobalt Strike启动运行&上线方法&插件
【内网安全-CS】Cobalt Strike启动运行&上线方法&插件
2741 0
【内网安全-CS】Cobalt Strike启动运行&上线方法&插件
|
Python Windows
升级pip并安装库
今天用pip安装一些常用库,然后出现以下这段代码。 需要升级一下pip
746 0
升级pip并安装库
|
4月前
|
编解码 算法 数据安全/隐私保护
手机常用压缩工具推荐,RAR,ZIP,7Z解压缩,zip解压缩,Bandizip,ZArchiver等解压工具
在手机上解压RAR、ZIP、7Z等格式文件时,选择一款功能强大的解压缩工具至关重要。本文介绍了多款实用的解压软件,如7Z解压缩、ZArchiver、RAR、Bandizip等,它们不仅支持多种压缩格式的解压和压缩,还具备文件管理、加密、分享、媒体预览等功能。无论是处理文档、图片还是视频,这些工具都能提供高效便捷的解决方案,满足日常使用需求。
1487 0
|
7月前
|
存储 SQL 运维
中国联通网络资源湖仓一体应用实践
本文分享了中国联通技术专家李晓昱在Flink Forward Asia 2024上的演讲,介绍如何借助Flink+Paimon湖仓一体架构解决传统数仓处理百亿级数据的瓶颈。内容涵盖网络资源中心概况、现有挑战、新架构设计及实施效果。新方案实现了数据一致性100%,同步延迟从3小时降至3分钟,存储成本降低50%,为通信行业提供了高效的数据管理范例。未来将深化流式数仓与智能运维融合,推动数字化升级。
326 0
中国联通网络资源湖仓一体应用实践
|
10月前
|
前端开发 Java Spring
springMVC前后端请求参数绑定和传递
通过上述配置和示例,您可以在 Spring MVC 中实现前后端请求参数的绑定和数据传递。无论是简单的基础数据类型还是复杂的对象,Spring MVC 都提供了简洁且强大的支持,使得开发过程更加高效和易于维护。
317 23
|
9月前
|
数据管理 Linux iOS开发
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
225 0
Splunk Enterprise 9.4.1 (macOS, Linux, Windows) 发布 - 机器数据管理和分析
|
缓存 网络协议 算法
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
[蓝桥杯嵌入式]hal库 stm32 PWM的使用(随时修改占空比,随时修改频率)
|
JavaScript 前端开发 IDE
TypeScript在大型前端项目中的价值与实践策略
【4月更文挑战第6天】本文探讨了TypeScript在大型前端项目中的价值和实践策略。 TypeScript通过静态类型检查、代码提示、接口与泛型提高代码质量和开发效率。它支持最新JS语法,拥有广泛社区支持。实践策略包括逐步迁移、制定类型规范、利用IDE、维护类型定义文件以及集成自动化测试。通过培训和知识分享,团队能更好地应用TypeScript,打造高质量、可维护的前端项目。
183 1
|
监控 Java 测试技术
Spring Boot与事务钩子函数:概念与实战
【4月更文挑战第29天】在复杂的业务逻辑中,事务管理是确保数据一致性和完整性的关键。Spring Boot提供了强大的事务管理机制,其中事务钩子函数(Transaction Hooks)允许开发者在事务的不同阶段插入自定义逻辑。本篇博客将详细探讨事务钩子函数的概念及其在Spring Boot中的应用。
342 1
|
存储
数字逻辑与模拟电子技术-部分知识点(4)——数电部分-组合电路的一般分析和设计方法、三人和四人表决器的设计、SR触发器、D触发器、JK触发器
数字逻辑与模拟电子技术-部分知识点(4)——数电部分-组合电路的一般分析和设计方法、三人和四人表决器的设计、SR触发器、D触发器、JK触发器
417 0