【问题标题】:Using _ (underscore) variable with arrow functions in ES6/Typescript在 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());
}

【问题讨论】:

  • 您怎么会担心从未使用过的参数的类型或类型特异性?
  • 我是一名 C++ 开发人员,所以我想我总是担心类型特异性 :-)。
  • 就个人而言,_=> 模式减少了括号的数量,使其更易于阅读:doStuff().then(()=>action()) vs doStuff().then(_=>动作())。

标签: javascript typescript ecmascript-6 arrow-functions


【解决方案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 主要是组合这些东西的新方法。
    猜你喜欢
    • 2019-12-17
    • 1970-01-01
    • 2016-12-22
    • 2016-08-06
    • 1970-01-01
    • 2018-01-08
    相关资源
    最近更新 更多