JavaScript 箭头函数:适用与不适用场景
作者:黄君发布时间:2020-10-28分类:计算机教程浏览:1087
现代 JavaScript 中最引人注目的功能之一是引入了箭头函数,用 => 来标识。
这种函数有两大优点 – 非常简洁的语法,和更直观的作用域和 this的绑定。
这些优点有时导致箭头函数比其他形式的函数声明更受欢迎。
例如,受欢迎的 airbnb eslint 配置 会在您创建匿名函数时强制使用JavaScript箭头函数。
然而,就像工程中的任何东西一样,箭头函数优点很明显,同时也带来了一些负面的东西。 使用他们的时候需要权衡一下。
学习如何权衡是更好地使用箭头函数的关键。
在本文中,我们将首先回顾箭头函数的工作原理,然后深入研究箭头函数改进代码的示例,最后深入研究箭不建议使用头函数的示例。
JavaScript 箭头函数究竟是什么?
JavaScript 箭头函数大致相当于 python 中的 lambda 函数 或 Ruby 中的 blocks。
这些是匿名函数,它们有自己的特殊语法,接受一定数量的参数,并在其封闭的作用域的上下文(即定义它们的函数或其他代码)中操作。
让我们依次分解这些部分。
箭头函数语法
箭头函数具有单一的总体结构,然后在特殊情况下可以通过多种方式简化它们。 核心结构如下所示:
(argument1, argument2, ... argumentN) => {
// function body
}
括号内的是参数列表,后跟“胖箭头”(=>),最后是函数体。
这与传统函数非常相似,我们只是省略 function 关键字并在参数后添加一个胖箭头(=>)。
然而,有许多方法可以简化箭头函数。
首先,如果函数体是单个表达式,则可以不使用花括号并将其置于内联中(省略大括号直接将表达式写在一行中)。 表达式的结果将由函数返回。 例如:
const add = (a, b) => a + b;
其次,如果只有一个参数,你甚至可以省略参数的括号。例如:
const getFirst = array => array[0];
正如您所看到的,这是一些非常简洁的语法,我们将重点介绍后面的好处。
高级语法
有一些高级语法可以了解一下。
首先,如果您尝试使用内联单行表达式语法,但您返回的值是对象字面量。您可能会认为这看起来应该是这样的:
(name, description) => {name: name, description: description};
问题是这种语法比较含糊不清,容易引起歧义 : 看起来好像你正试图创建一个传统的函数体。 如果你碰巧想要一个对象的单个表达式,请用括号包裹该对象:
(name, description) => ({name: name, description: description});
封闭的上下文作用域
与其他形式的函数不同,箭头函数没有自己的 执行期上下文。
实际上,这意味着 this 和 arguments 都是从它们的父函数继承而来的。
例如,使用和不使用箭头函数比较以下代码:
const test = {
name: 'test object',
createAnonFunction: function() {
return function() {
console.log(this.name);
console.log(arguments);
};
},
createArrowFunction: function() {
return () => {
console.log(this.name);
console.log(arguments);
};
}
};
我们有一个简单的 test 对象,有两个方法 – 每个方法都返回一个匿名函数。
不同之处在于第一个方法使用传统函数表达式,而后者中使用箭头函数。
如果我们使用相同参数,在控制台中运行它们,我们会得到完全不一样的结果。
> const anon = test.createAnonFunction('hello', 'world');
> const arrow = test.createArrowFunction('hello', 'world');
> anon();
undefined
{}
> arrow();
test object
{ '0': 'hello', '1': 'world' }
第一个匿名函数有自己的函数上下文,因此当您调用它时,test 对象的 this.name 没有可用的引用,也没有创建它时调用的参数。
另一个,箭头函数具有与创建它的函数完全相同的函数上下文,使其可以访问 argumetns 和 test 对象。
使用箭头函数改进您的代码
传统 lambda 函数的主要用例之一,就是用于遍历列表中的项,现在用 JavaScript 箭头函数实现。
比如你有一个有值的数组,你想去 map 遍历每一项,这时使用箭头函数非常理想:
const words = ['hello', 'WORLD', 'Whatever'];
const downcasedWords = words.map(word => word.toLowerCase());
一个非常常见的例子是提取对象中的某个特定值:
const names = objects.map(object => object.name);
类似地,当用现代迭代样式取代传统的 for 循环,一般我们使用 forEach 循环,箭头函数能够保持 this 来自于父级,让他们非常直观
类似的,当用 forEach 来替换传统 for循环的时候,实际上箭头函数会直观的保持 this来自于父一级
this.examples.forEach(example => {
this.runExample(example);
});
Promises 和 Promise 链
箭头函数的另一个可以使代码更清晰,更直观的地方是管理异步代码。
Promises 使得管理异步代码变得容易很多(即使你很欢快地使用 async / await,你仍然应该理解 async / await 是建立在 Promises 之上的 !)
但是,虽然使用 promises 仍然需要定义在异步代码或调用完成后运行的函数。
这是箭头函数的理想位置,特别是如果您生成的函数是有状态的,同时想引用对象中的某些内容。 例如:
this.doSomethingAsync().then((result) => {
this.storeResult(result);
});
对象转换
箭头函数的另一个常见且极其强大的用途是封装对象转换。
例如,在 Vue.js 中,有一种通用模式,用于使用 mapState 将 Vuex 存储的各个部分直接包含到 Vue 组件中。
这涉及定义一组 “mappers” ,这些 “mappers” 将从原始的完整的 state 对象转换为提取所涉及组件所需的内容。
这些简单的转换使用箭头函数再合适不过了。比如:
export default {
computed: {
...mapState({
results: state => state.results,
users: state => state.users,
});
}
}
你不应该使用箭头函数的情景
在许多情况下,使用箭头函数不是一个好主意。 他们不仅不会帮助你,而且会给你带来一些不必要的麻烦。
第一个是对象的方法。 这是一个函数上下文的例子,这对于我们理解很有帮助。
有一段时间使用 Class(类)属性语法和箭头函数的组合,作为创建“自动绑定方法”的方式,例如, 事件处理程序可以使用,但仍然绑定到类的方法。
这看起来像是这样的:
class Counter {
counter = 0;
handleClick = () => {
this.counter++;
}
}
这样,即使 handleClick 由事件处理程序调用,而不是在 Counter 实例的上下文中调用,它仍然可以访问实例的数据。
这种方法的缺点很多,在本文中很好地记录。
虽然使用这种方法确实为您提供了具有绑定函数的快捷方式,但该函数以多种不直观的方式运行,如果您尝试将此对象作为原型进行子类化/使用,则会不利于测试,同时也会产生很多问题。
相反,使用常规函数,如果需要,将其绑定到构造函数中的实例:
class Counter {
counter = 0;
handleClick() {
this.counter++;
}
constructor() {
this.handleClick = this.handleClick.bind(this);
}
}
深层的调用链
箭头函数可能让你遇到麻烦的另一个地方是,它们被用于许多不同的组合,特别是在函数深层调用链中。
核心原因与匿名函数相同 – 它们给出了非常糟糕的堆栈跟踪。
如果你的函数只是向下一级,比如在迭代器里面,那也不是太糟糕,但是如果你把所有的函数定义为箭头函数,并在它们之间来回调用,你就会陷入困境 遇到一个错误的时候,只是收到错误消息,如:
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
{anonymous}()
有动态上下文的函数
箭头函数可能让您遇到麻烦的最后一种情况就是吗, this 是动态绑定的时候。
如果您在这些位置使用箭头函数,那么动态绑定将不起作用,并且你(或稍后使用你的代码的其他人)可能会对事情未按预期执行的原因感到困惑。
一些典型的例子:
事件处理程序是通过将 this 设置为事件的 currentTarget 属性来调用。
如果您仍在使用 jQuery ,则大多数 jQuery 方法将 this 设置为已选择的 dom 元素。
如果您正在使用 Vue.js ,则方法和计算函数通常将 this 设置为 Vue 组件。
当然你可以故意使用箭头函数来覆盖这种行为,但特别是在 jQuery 和 Vue 的情况下,这通常会干扰正常运行,让你感到困惑的是为什么看起来与附近其他代码相同的代码不起作用。
总结
箭头函数是 JavaScript 语言的一个非常有必要的补充,并且在许多情况下使代码更符合人们的阅读习惯。
然而,像所有其他特性一样,它们有优点和缺点。 我们应该将它们作为我们工具箱中的另一个工具,而不是作为所有函数的全面替代品。
- 上一篇:高中生学什么专业有前途?零基础学java
- 下一篇:高中生能学会编程吗?
- 计算机教程排行
-
- 1汕头信息:“公共就业服务进校园”粤东专场在汕头大学举行|||计算机网络培训学校
- 2江门信息:构建和谐劳动关系优化提升营商环境江门市开展推进新时代和谐劳动关系创建活动|||广州学电脑培训学校
- 3汕头信息:2024年广东省公共就业服务进校园粤东片区专场活动诚邀各用人单位参会|||广州计算机编程培训
- 4广州中考成绩公布,高中阶段学校录取控制分数线公布,普高最低控制线502分
- 5清远信息:校企双向奔赴清远市人社部门携企赴省内外高校招才引智|||广州计算机编程培训
- 6江门信息:工伤保险缴费误区:最低工资非缴费基准,违规用人单位将面临法律风险!|||计算机软件培训学校
- 7惠州信息:2024年第一季度惠州人力资源市场供求情况|||北大青鸟计算机培训中心
- 8惠州信息:“惠州市就业驿站巡礼”之惠阳新圩站|||大学生计算机培训学校
- 9汕尾信息:世界技能大赛获奖选手全省巡回宣讲交流活动走进汕尾|||电脑计算机编程培训学校
- 标签列表
-
- Java (3694)
- 北大青鸟 (3713)
- 软件开发 (3613)
- JAVA (3413)
- UI设计入门 (2093)
- 惠州北大青鸟 (4375)
- 惠州IT培训 (2558)
- UI设计培训 (2090)
- 惠州UI设计培训 (2095)
- 惠州UI设计培训学校 (2090)
- 惠州计算机软件培训 (6260)
- 惠州计算件软件开发 (6260)
- 惠州计算机软件基础 (6261)
- 惠州计算机JAVA培训 (3574)
- 惠州计算机Java软件开发 (3620)
- 惠州计算机JAVA软件开发 (4645)
- 惠州计算机JAVA软件开发学校 (3338)
- 惠州计算机Java软件开发培训 (3338)
- 北大青鸟IT计算机学校 (5048)
- 北大青鸟IT软件学校 (5062)
- 北大青鸟IT学校 (5059)
- 惠州计算机UI设计软件开发 (2088)
- UI设计基础教程 (2088)
- UI设计是什么 (2088)
- UI设计教程 (2088)
- 网站分类
-
- 计算机教程
- 计算机入门
- 职业学校
- 新闻动态
- 专业课程
- 热门技术
- SEO
- 培训教程
- windows
- linux教程
- 系统集成
- 网站开发
- Html5
- 办公软件
- 师资力量
- 热点问答
- 联系我们
- 计算机学校
- 惠州计算机学校
- 河源计算机学校
- 广州计算机学校
- 深圳计算机学校
- 湛江计算机学校
- 佛山计算机学校
- IT计算机培训信息
- 设计专业
- UI
- 影视特效
- 游戏动漫设计
- Photoshop
- AI设计
- 软件教程
- Java技术
- C语言/C++语言培训
- C#
- Python技术
- PHP
- 数据库
- SQL Server
- 网络教程
- 网络安全
- 网络营销
- 软件专业
- 大数据专业
- 前端开发专业
- 软件测试专业
- Python专业
- 软件实施
- 珠海计算机学校
- 初中生学什么好
- 计算机认证
- 文章归档
-
- 2024年11月 (14)
- 2024年10月 (32)
- 2024年9月 (29)
- 2024年8月 (68)
- 2024年7月 (59)
- 2024年6月 (43)
- 2024年5月 (48)
- 2024年4月 (80)
- 2024年3月 (65)
- 2024年2月 (54)
- 2024年1月 (25)
- 2023年12月 (12)
- 2023年11月 (73)
- 2023年10月 (134)
- 2023年9月 (34)
- 2023年8月 (3)
- 2023年7月 (3)
- 2023年6月 (12)
- 2023年5月 (30)
- 2023年4月 (72)
- 2023年3月 (11)
- 2023年2月 (34)
- 2023年1月 (37)
- 2022年12月 (78)
- 2022年11月 (359)
- 2022年6月 (1193)
- 2022年5月 (570)
- 2022年4月 (1567)
- 2022年3月 (982)
- 2022年2月 (54)
- 2022年1月 (182)
- 2021年9月 (308)
- 2021年8月 (1704)
- 2021年7月 (2423)
- 2021年6月 (1806)
- 2021年5月 (1569)
- 2021年4月 (1380)
- 2021年3月 (1255)
- 2021年2月 (709)
- 2021年1月 (1521)
- 2020年12月 (3626)
- 2020年11月 (1646)
- 2020年10月 (1046)
- 2020年9月 (592)
- 最近发表
-
- 清远信息:2024年广清杯清远南粤家政技能大赛举行决赛|||计算机培训机构
- 汕尾信息:陈良川带队到汕尾技师学院调研|||计算机职业技能培训班
- 东莞信息:凤岗凤岗镇组织召开社保参保缴费及劳动用工政策宣讲会|||计算机软件培训学校
- 阳江信息:2024年度注册城乡规划师职业资格考试的合格标准是怎样的?|||计算机软件培训学校
- 阳江信息:职业技能提升补贴对象有哪些?|||大学生计算机培训学校
- 清远信息:清远市首家社保服务合作网点在清城区举办启动仪式|||计算机职业技能培训班
- 汕头信息:招聘658名中高端人才!2024年汕头市引进中高端人才专场招聘会举行|||北大青鸟计算机培训中心
- 东莞信息:广东省社保智能经办现场会在东莞召开|||大学生计算机培训学校
- 东莞信息:东坑镇举办2024年重点群体系列招聘活动|||计算机职业技能培训班
- 东莞信息:万江万江街道成功举办第四届粤菜师傅烹饪技能竞赛|||广州计算机编程培训