在 ES6/Typescript 中使用带有箭头函数的 _(下划线)变量
Posted
技术标签:
【中文标题】在 ES6/Typescript 中使用带有箭头函数的 _(下划线)变量【英文标题】:Using _ (underscore) variable with arrow functions in ES6/Typescript 【发布时间】:2017-04-26 09:27:52 【问题描述】:我在一个 Angular 示例中遇到了这个结构,我想知道为什么选择它:
_ => console.log('Not using any parameters');
我了解变量 _
表示不关心/未使用,但由于它是唯一变量,因此有任何理由更喜欢使用 _
:
() => console.log('Not using any parameters');
当然,这不能少一个字符来输入。 ()
语法在我看来更好地传达了意图,并且也更具体,因为否则我认为第一个示例应该如下所示:
(_: any) => console.log('Not using any parameters');
如果它很重要,这是使用它的上下文:
submit(query: string): void
this.router.navigate(['search'], queryParams: query: query )
.then(_ => this.search());
【问题讨论】:
***.com/questions/18300654/… 您怎么会担心从未使用过的参数的类型或类型特异性? 我是一名 C++ 开发人员,所以我想我总是担心类型特异性 :-)。 就个人而言,_=> 模式减少了括号的数量,使其更易于阅读:doStuff().then(()=>action()) vs doStuff().then(_=>动作())。 【参考方案1】:可以区分这两种用法,有些框架用它来表示不同类型的回调。例如,我认为nodes express框架使用它来区分中间件的类型,例如错误处理程序使用三个参数,而路由使用两个。
这样的区分可以像下面的例子:
const f1 = () => // A function taking no arguments
const f2 = _ => // A function with one argument that doesn't use it
function h(ff)
if (ff.length === 0)
console.log("No argument function - calling directly");
ff();
else if (ff.length === 1)
console.log("Single argument function - calling with 1");
ff(1);
h(f1);
h(f2);
这是基于 Bergi 的回答,但我认为添加一个示例比我乐意对其他人的帖子进行更多的编辑。
【讨论】:
【参考方案2】:可以使用这种样式的原因(也可能是这里使用的原因)是_
比()
短一个字符。
可选括号属于与optional curly brackets 相同的样式问题。这在很大程度上是一个品味和代码风格的问题,但由于一致性,这里更喜欢冗长。
虽然箭头函数允许单个参数不带括号,但它与零、单个解构、单个休息和多个参数不一致:
let zeroParamFn = () => ... ;
let oneParamFn = param1 => ... ;
let oneParamDestructuredArrFn = ([param1]) => ... ;
let oneParamDestructuredObjFn = ( param1 ) => ... ;
let twoParamsFn = (param1, param2) => ... ;
let restParamsFn = (...params) => ... ;
虽然is declared but never used
错误was fixed in TypeScript 2.0 用于下划线参数,_
也可以触发来自 linter 或 IDE 的 unused variable/parameter
警告。这是反对这样做的一个相当大的论据。
_
通常可用于忽略参数(正如已解释的其他答案)。虽然这可能被认为是可以接受的,但这种习惯可能会导致与_
Underscore/Lodash 命名空间发生冲突,当有多个被忽略的参数时也会看起来很混乱。因此,正确命名带下划线的参数(在 TS 2.0 中支持)是有益的,还可以节省时间来确定函数签名以及为什么将参数标记为忽略(这违背了 _
参数作为快捷方式的目的):
let fn = (param1, _unusedParam2, param3) => ... ;
由于上面列出的原因,我个人认为_ => ...
代码风格是一种应该避免的不良语气。
【讨论】:
它短了一个字符,但对于大多数 IDE 来说,按键次数是相同的,因为按下(
通常会带有)
。我个人更喜欢使用p
作为参数,我也想知道它是否有任何性能问题
@Mojimi 您可能必须按)
或右箭头键才能跳过该字符。【参考方案3】:
()
语法更好地传达了意图,并且也更具体
不完全是。 ()
表示该函数不需要任何参数,它不声明任何参数。该函数的.length
为0。
如果您使用_
,它明确声明该函数将被传递一个参数,但您并不关心它。该函数的.length
将为1,这在某些框架中可能很重要。
所以从类型的角度来看,这样做可能更准确(尤其是当您不使用any
键入它,而是使用_: Event
时)。正如你所说,它少了一个字符,在某些键盘上也更容易输入。
【讨论】:
我的第一个想法是 _ 只是按照惯例很明显,在尝试理解函数时不需要考虑任何参数。使用 () 使其明确,无需扫描代码以查找可能使用的 _ (这将违反约定)。但是你睁开眼睛也考虑了记录有一个值传递给函数的价值,否则这并不总是显而易见的。 我刚刚意识到我的代码中充满了未使用的_
s箭头函数变量,我想知道与使用()
相比是否有任何性能差异
我不确定我是否遵循您的第二段。下划线意味着您不打算使用它怎么办?你当然可以,对吧?
@isherwood 你可以,是的,但是你应该给它一个合适的名字(即使像e
这样的短名称表示“事件”)。 The conventions isthat _
identifies an unused variable.【参考方案4】:
我猜_ =>
只是在() =>
上使用,因为_
在其他语言中很常见,不允许像在 JS 中那样只省略参数。
_
在 Go 中很流行,在 Dart 中也使用它来表示一个参数被忽略,可能还有其他我不知道的参数。
【讨论】:
我认为 Python 也遵循这个约定。_
的这种用法大概是从 ML 和 Haskell 等函数式语言中借用的,它早于 Python 的发明(更不用说 Go、Dart 或 TypeScript)了。
Ruby 也能做到这一点 (po-ru.com/diary/rubys-magic-underscore) 和 F#(以及受 ML 家族影响的其他语言)
Scala 喜欢下划线 (includehelp.com/scala/use-of-underscore-in-scala.aspx)。在 Scala 对带下划线的匿名类型所做的工作之后,还有哪些语言采用了。
我猜 Scala 也从其他一些语言中获取了它。在 70 年代,编程语言中几乎没有什么是不存在的:D 主要是组合这些东西的新方法。以上是关于在 ES6/Typescript 中使用带有箭头函数的 _(下划线)变量的主要内容,如果未能解决你的问题,请参考以下文章
如何在带有 React 的 Typescript/JSX 中使用带有箭头函数的泛型?