少年,不要滥用箭头函数啊

EfficientNet中的MBConv模块详解:为什么它能如此高效? 本文深度解析了EfficientNet中的MBConv模块,详细介绍了其核心设计理念、效率优化技术和复合缩放理论。MBConv通过深度可分离卷积、倒残差结构和注意力机制三大关键技术,实现了计算效率与模型性能的平衡,成为高效网络结构设计的典范。 阅读详情

在ES6大行其道的今天,不应用点ES6特性似乎有些政治不正确。最近刚好有个Node的项目,最低要支持到nodejs 4.0,在node.green看了下ES6的支持度,我想使用的特性基本都有支持,遂决定在新项目中采用ES6来写。

当然第一件事情就是毫不留情地消灭var,项目中能用const的地方不用let,能用let的地方不用var。

第二件事情就是使用劳动人民喜闻乐见的箭头函数替代function。当我心满意足地看到满屏的=>时,现实给了我一记响亮的耳光——改过之后的程序错误百出!

所以,当我们使用箭头函数时,一定要搞清楚箭头函数是什么回事,适用于什么场景。本文就针对以上问题来讨论下箭头函数。

箭头函数是什么?

箭头函数的语法我就不讲了,相信大家都见识过。跟我一样,大家喜欢箭头函数90%的原因是它好看。除了好看,它是不是与function等价呢?肯定不等价,因为TC39不可能仅因为好看而引入一个语法糖(class除外)。

箭头函数的渊源可以追溯到上古时期一个叫lambda演算的东西。lambda演算是数学家提出来的,有些数学家跟我们程序员一样也很懒,数学定理那么多,今天要证三角定律,明天要证勾股定律,累不累!那能不能将所有的证明问题用一个统一的体系进行形式化描述,然后由机器来完成自动推导呢?lambda演算就是干这个的,图灵也搞了一套体系叫图灵机,两者是等价的。

关于lambda演算说了这么多,好像跟今天要讲的箭头函数没什么关系?其实是有关系的,lambda演算深刻影响了箭头函数的设计。数学家们喜欢用纯函数式编程语言,纯函数的特点是没有副作用,给予特定的输入,总是产生确定的输出,甚至有些情况下通过输出能够反推输入。要实现纯函数,必须使函数的执行过程不依赖于任何外部状态,整个函数就像一个数学公式,给定一套输入参数,不管是在地球上还是火星上执行都是同一个结果。

箭头函数要实现类似纯函数的效果,必须剔除外部状态。所以当你定义一个箭头函数,在普通函数里常见的this、arguments、caller是统统没有的。

箭头函数没有this

箭头函数没有this,那下面的代码明显可以取到this啊:

function foo() {
  this.a = 1
  let b = () => console.log(this.a)

  b()
}

foo()  // 1

以上箭头函数中的this其实是父级作用域中的this,即函数foo的this。箭头函数引用了父级的变量,构成了一个闭包。以上代码等价于:

function foo() {
  this.a = 1

  let self = this
  let b = () => console.log(self.a)

  b()
}

foo()  // 1

箭头函数不仅没有this,常用的arguments也没有。如果你能获取到arguments,那它一定是来自父作用域的。

function foo() {
  return () => console.log(arguments[0])
}

foo(1, 2)(3, 4)  // 1

上例中如果箭头函数有arguments,就应该输出的是3而不是1。

一个经常犯的错误是使用箭头函数定义对象的方法,如:

let a = {
  foo: 1,
  bar: () => console.log(this.foo)
}

a.bar()  //undefined

以上代码中,箭头函数中的this并不是指向a这个对象。对象a并不能构成一个作用域,所以再往上到达全局作用域,this就指向全局作用域。如果我们使用普通函数的定义方法,输出结果就符合预期,这是因为a.bar()函数执行时作用域绑定到了a对象。

let a = {
  foo: 1,
  bar: function() { console.log(this.foo) }
}

a.bar()  // 1

另一个错误是在原型上使用箭头函数,如:

function A() {
  this.foo = 1
}

A.prototype.bar = () => console.log(this.foo)

let a = new A()
a.bar()  //undefined

同样,箭头函数中的this不是指向A,而是根据变量查找规则回溯到了全局作用域。同样,使用普通函数就不存在问题。

通过以上说明,我们可以看出,箭头函数除了传入的参数之外,真的是什么都没有!如果你在箭头函数引用了this、arguments或者参数之外的变量,那它们一定不是箭头函数本身包含的,而是从父级作用域继承的。

什么情况下该使用箭头函数

到这里,我们可以发现箭头函数并不是万金油,稍不留神就会踩坑。

至于什么情况该使用箭头函数,《You Don’t Know JS》给出了一个决策图: arrow

以上决策图看起来有点复杂,我认为有三点比较重要:

  1. 箭头函数适合于无复杂逻辑或者无副作用的纯函数场景下,例如用在map、reduce、filter的回调函数定义中;
  2. 不要在最外层定义箭头函数,因为在函数内部操作this会很容易污染全局作用域。最起码在箭头函数外部包一层普通函数,将this控制在可见的范围内;
  3. 如开头所述,箭头函数最吸引人的地方是简洁。在有多层函数嵌套的情况下,箭头函数的简洁性并没有很大的提升,反而影响了函数的作用范围的识别度,这种情况不建议使用箭头函数。
vesta软件_分子动力学计算实战:利用 OVITO 软件找弗伦克尔缺陷和位错环分析 今天继续和大家分享这篇纯分子动力学(MD)的 Nat. Comm. 文章(DOI:10.1038/s41467-018-07102-3)。上期推文(从一篇 Nat. Comm. 学习经典分子动力学基本知识和相关软件基本操作 (一)),我们借用该文章的 fig.1 简单介绍了如何用文中所提到的 LAMMPS 软件来实现材料中级联碰撞过程。但是,想完整的展示类似该文章的 fig.1,单纯利用... 阅读详情

相关推荐

什么是plm系统?-数字化转型网

当今世界,产品研发能力是企业在激烈的市场竞争中保持战略优势的核心竞争力之一。如何有效地缩短产品研发周期、改善产品服务的设计迭代流程、有效降低产品的研发成本,也是企业面临的主要问题之一。PLM(Product Lifecycle Management,产品生命周期管理)在优化产品研发的全管理流程、增强企业产品的市场竞争力方面具有关键的作用。

cxo17757154043的博客 882

lambda中使用filter过滤

单一条件过滤 /** * 测试filter */ @Test public void testFilter() { List<User> user = new ArrayList<>(); user.add(new User(1L, 18, "小明")); user.add(new User(2L, 20, "小王")); user.add(new User(3L, 28

小泽 3710

2025反爬虫革命:京东商品接口的动态指纹认证与量子加密传输方案

在2025年,全球电商API接口面临的安全威胁呈现指数级增长:京东构建了基于硬件、软件、行为三重维度的设备指纹模型:京东构建了基于BB84+E91混合协议的量子密钥中继网络:

FB13713612741的博客 1648

lambda、map、filter

1.实现两个长度相同的列表对应元素相减 l1 =[1, 2], l2 =[3, 4] l = list(map(lambda x: x[0]-x[1], zip(l1, l2)))

NeverFadeAway的博客 219

Ubuntu使用gstreamer开发USB相机应用(一)

Ubuntu使用gstreamer开发USB相机应用(一) 包括:gstreamer安装,测试。使用v4l2测试USB相机。使用gstreamer采集相机

Alon1787的博客 2739

叶绿体基因组提交NCBI全流程避坑指南

叶绿体基因组作为环状细胞器DNA,其数据提交并非简单上传,而是需严格遵循INSDC标准的学术出版行为。其核心原理在于元数据完整性、拓扑结构语义一致性与分类学路径精确匹配;技术价值体现在保障序列可追溯、可复现、可互操作;典型应用场景涵盖植物系统发育、条形码开发及合成生物学底盘构建。实践中,FASTA头行格式、feature table嵌套规则、taxid绑定及BankIt静默校验等环节极易引发失败。本文聚焦NCBI|叶绿体基因组数据上传中的高频报错与隐性约束,提供面向生物信息工程师的实操级规范解析。

weixin_31960565的博客 325

JAvaScript之函数声明和函数表达式的区别

1 函数声明和函数表达式 函数声明 //函数的声明 function f1() { console.log("我是函数"); } f1(); 函数表达式(推荐使用) //函数表达式 var ff=function () { console.log("我也是一个函数"); }; ff(); 函数声明和函数表达式的区...

qq_41320857的博客 626

0基础手把手搭建 Trae\+Seedance2\.0 真人短剧生成智能体(可直接运行)

前言:本文专为0基础新手编写,全程无复杂代码、无专业术语,一步一截图提示(操作路径清晰),只需跟着点鼠标、复制粘贴,就能搭建出可自动生成真人短剧的智能体,生成的短剧可直接导出发布。核心工具:Trae(字节跳动AI IDE,免费)+ Seedance2.0(真人视频生成API,公测免费),无需提前学习编程、设计,全程10-15分钟搞定。 适用人群:0基础小白、想快速生成真人短剧(自媒体、短视频创作者)、无需懂技术即可实现自动化短剧生成的人群。

skygulangfendouz的专栏 1058

filter和lambda使用

filter函数 filter(self, /, *args, **kwargs)-----过滤 filter() 函数用于过滤序列,过滤掉不符合条件的元素,返回由符合条件元素组成的新列表。 该接收两个参数,第一个为函数,第二个为序列,序列的每个元素作为参数传递给函数进行判,然后返回 True 或 False,最后将返回 True 的元素放到新列表中。 例如:实例 def is_odd(n): r...

peichym的博客 2178

如何在 Ubuntu 24.04 LTS 上安装 SSH 服务器?

Ubuntu是一个基于Debian的开源Linux操作系统,由Canonical Ltd.开发和维护。Ubuntu致力于提供用户友好、稳定且安全的操作系统环境,适用于个人用户、企业和服务器等不同场景。Ubuntu 24.04 LTS是Ubuntu发布的一个长期支持版本,LTS代表长期支持(Long Term Support)。这意味着Ubuntu 24.04 LTS将获得长达5年的安全更新和维护支持,使其成为企业和个人用户的理想选择。

网络技术联盟站 5888

SLAM Cartographer(18)后端优化问题求解器

了解经过闭环检测构建了子图与节点之间的约束之后,通过后端优化求解器进行优化求解。核心是基于Ceres库进行SPA(Sparse Pose Adjustment)的优化方法,把后端优化问题描述成为一个最小二乘的问题求解

氢键H-H 5680

JavaScript lambda 表达式介绍

一些初学者在工作中遇到 lambda 表达式时会感到困惑,说:“好吧,这是什么写法?”和那些新手一样,这篇文章是为那些第一次遇到 lambda 表达式时感到困惑的人写的。这次我将使用 JavaScript 解释 lambda 表达式,但同样的想法也可以应用于其他语言。目录您将能够读写 lambda 表达式!在 JavaScript 中,您可以将函数放入变量中或将其作为参数传递。例如,像这样。 Example2 中出现的是一个函数,它在 X 毫秒后执行第一个参数接收到的函数(X 是第二个参数接收到的数字

allway2的博客 6665

VB摄像头监控

该VB模块可对摄像头捕获的画面进行录像等,可在创建的窗口进行控制

js map 箭头_少年,不要滥用箭头函数啊:JS中lambda表达式的优缺点和使用场景

在ES6大行其道的今天,不应用点ES6特性似乎有些政治不正确。最近刚好有个Node的项目,最低要支持到nodejs 4.0,在node.green看了下ES6的支持度,我想使用的特性基本都有支持,遂决定在新项目中采用ES6来写。当然第一件事情就是毫不留情地消灭var,项目中能用const的地方不用let,能用let的地方不用var。第二件事情就是使用劳动人民喜闻乐见的箭头函数替代function。...

weixin_35223575的博客 426

汉书HE8,好用的汇编代码编写工具

汉书HE8,好用的汇编代码编写工具早期编写汇编代码所用功能强大

Data-Structures-and-Algorithm-Analysis-in-Java.pdf

作者: Weiss, Mark A. 出版社: Addison Wesley Data Structures and Algorithm Analysis in Java is an “advanced algorithms” book that fits between traditional CS2 and Algorithms Analysis courses. In the old ACM Curriculum Guidelines, this course was known as CS7. This text is for readers who want to learn good programming and algorithm analysis skills simultaneously so that they can develop such programs with the maximum amo...

停止滥用箭头函数:这5个场景请务必使用 function

停止滥用箭头函数:这5个场景请务必使用 function

幽幽谷 786

锂电池充电器电路设计 里面有电路

锂电池充电器电路设计 里面有电路 3.7V升压到5V电路设计。

ES6新特性箭头函数语法、如何正确使用箭头函数

ES6标准新增了一种新的函数:Arrow Function(箭头函数)。 基础语法 通常函数的定义方法 var fn1 = function(a, b) { return a + b } function fn2(a, b) { return a + b } 使用ES6箭头函数语法定义函数,将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参数...

qq_32614411的博客 8万+

别再滥用箭头函数了!这 5 种情况必须用 `function`

箭头函数简洁,但不是万能。

Caleb的博客 370

1、什么是箭头函数

目录基础语法箭头函数与function的区别1、this的指向:2、构造函数3、变量提升什么时候不该使用箭头函数1、在对象上定义函数2、在原型上定义函数3、动态上下文中的回调函数4、构造函数中 基础语法 通常函数的定义方法 var fn1 = function(a, b) { return a + b } function fn2(a, b) { return a + b } 使用ES6箭头函数语法定义函数,将原函数的“function”关键字和函数名都删掉,并使用“=>”连接参

abuanden的博客 1万+

箭头函数有哪些特性

分别是this指向、构造函数、arguments对象、隐式返回值和类成员方法

从人到猿 3760

为什么使用箭头函数

转发https://segmentfault.com/a/1190000009410939 一 为什么要有箭头函数 我们在日常开发中,可能会需要写类似下面的代码 const Person = { 'name': 'little bear', 'age': 18, 'sayHello': function () { setInterval(functi...

DiegoBrother的博客 3949

前端JavaScript篇之箭头函数与普通函数的区别、如果new一个箭头函数的会怎么样、箭头函数的this指向哪⾥?

箭头函数和普通函数是 JavaScript 中的两种不同的函数形式,它们在语法和行为上存在一些区别。

星辰迷上大海的博客 1733

methods 中配置的函数,不要用箭头函数?

中的函数通常需要访问组件实例(也就是 VM,即 ViewModel)的属性和方法,例如。将不再指向组件实例,而是继承自其外部作用域,可能会导致意外的行为或错误。中的方法,因为 Vue 在调用这些方法时会确保将正确的上下文绑定给。这是因为箭头函数在定义时会捕获其上下文的。这样可以确保在方法内部能够正确地访问组件的属性和方法。中使用箭头函数,以免造成意外的行为和错误。指向组件实例,应该使用普通函数来定义。在 Vue.js 中,确实不建议在。,而是继承自外部作用域的。中的函数,那么函数中的。在 Vue 组件中,

思索的涟漪,突破自我 961

箭头函数的使用

箭头函数的使用基本用法为什么要有箭头函数和普通函数的区别不绑定this不绑定arguments什么时候不能用箭头函数 基本用法 ES6 允许使用“箭头”(=>)定义函数。 var f = v => v; 上面的箭头函数等同于: var f = function(v) { return v; }; 如果箭头函数不需要参数或需要多个参数,就使用一个圆括号代表参数部分。 var f ...

我是谁的博客 1874

箭头函数详解

箭头函数的定义、箭头函数参数以及返回值、解构赋值、箭头函数的使用注意点、箭头函数的this指向问题、箭头函数不适用场合问题。

分享互联网的有趣知识~ 3191

javaScript之箭头函数

在JavaScript中,箭头函数(Arrow Function)是一种使用箭头(=>)定义函数的新语法。它的引入为函数表达式提供了更简洁的语法,并且不绑定自己的this、arguments、super或new.target。1、箭头函数有一个参数的时候可以省略小括号2、箭头函数返回值只有一条语句时可以省略return和{}3、箭头函数没有内置对象arguments*4、箭头函数不是构造函数,不能构造实例化对象5、箭头函数的this不能发生改变,call和apply能调用箭头函数。

weixin_62160709的博客 3408

JS箭头函数学习

箭头函数是 ES6 中引入的一种新的函数声明语法,它提供了更简洁的语法形式,并且具有一些特点和注意事项。

qq_44327851的博客 1047
上一篇: RaphaelJS一些细节的学习
下一篇: React中constructor(props){}究竟是什么,以及super(props)与super()的区别
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付元
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值