在 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 中使用带有箭头函数的泛型?

为啥我不能在 JavaScript/ES6 中使用带有箭头函数的`new`? [复制]

如何禁止在Qt中使用带有按钮的键盘上的箭头键

TypeScript

不能使用带有返回 void 类型提示的箭头函数

带有异步和等待的箭头函数在本机反应中