Использование переменной _ (подчеркивание) со стрелочными функциями в ES6/Typescript

Я столкнулся с этой конструкцией в примере Angular, и мне интересно, почему это выбрано:

_ => console.log('Not using any parameters');

Я понимаю, что переменная _ означает, что она не заботится/не используется, но поскольку она является единственной переменной, есть ли основания предпочитать использование _ over:

() => 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());
}
38
задан Halt 11 дек. '16 в 13:28
источник поделиться

4 ответов

Причина, по которой этот стиль может быть использован (и, возможно, почему он использовался здесь), заключается в том, что _ - это один символ короче ().

Дополнительные круглые скобки попадают в ту же проблему стиля, что и необязательные фигурные скобки. Это вопрос стиля вкуса и кода по большей части, но многословие здесь предпочтительнее из-за последовательности.

В то время как функции стрелок допускают единственный параметр без круглых скобок, он несовместим с нулевым, одиночным деструктурированным, одним отдыхом и несколькими параметрами:

let zeroParamFn = () => { ... };
let oneParamFn = param1 => { ... };
let oneParamDestructuredArrFn = ([param1]) => { ... };
let oneParamDestructuredObjFn = ({ param1 }) => { ... };
let twoParamsFn = (param1, param2) => { ... };
let restParamsFn = (...params) => { ... };

Хотя is declared but never used ошибка была исправлена ​​в TypeScript 2.0 для подчеркнутых параметров, _ также может вызывать предупреждение unused variable/parameter из linter или IDE. Это значительный аргумент против этого.

_ можно условно использовать для игнорируемых параметров (как уже объяснил другой ответ). Хотя это можно считать приемлемым, эта привычка может привести к конфликту с пространством имен _ Underscore/Lodash, также выглядит запутанным, когда есть несколько игнорируемых параметров. По этой причине полезно иметь правильно названные подчеркнутые параметры (поддерживаемые в TS 2.0), а также экономит время на определение сигнатуры функции и почему параметры отмечены как игнорируемые (это не соответствует цели параметра _ как ярлык):

let fn = (param1, _unusedParam2, param3) => { ... };

По причинам, перечисленным выше, я лично считаю, что стиль кода _ => { ... } - это плохой тон, которого следует избегать.

30
ответ дан estus 11 дек. '16 в 15:52
источник поделиться

Синтаксис () передает намерение лучше imho, а также более специфичный тип

Не совсем. () говорит, что функция не ожидает никаких аргументов, она не объявляет никаких параметров. Функция .length равна 0.

Если вы используете _, он явно заявляет, что функции будет передан один аргумент, но вам это неинтересно. Функция .length будет 1, что может иметь значение в некоторых рамках.

Итак, с точки зрения типа, это может быть более точная вещь (особенно если вы не вводите ее с any, но, скажем, _: Event). И, как вы сказали, это один символ меньше, чтобы набирать, что также легче достичь на некоторых клавиатурах.

31
ответ дан Bergi 11 дек. '16 в 15:00
источник поделиться

Я предполагаю, что _ => используется только () =>, потому что _ распространен в других языках, где не разрешается просто опускать такие параметры, как в JS.

_ популярен в Go, а также используется в Dart, чтобы указать, что параметр игнорируется и, возможно, другие, о которых я не знаю.

17
ответ дан Günter Zöchbauer 11 дек. '16 в 13:36
источник поделиться

Возможно различать два способа использования, и некоторые структуры используют это для представления различных типов обратных вызовов. Например, я думаю, что узлы express framework используют это, чтобы различать типы промежуточного программного обеспечения, например обработчики ошибок используют три аргумента, в то время как маршрутизация использует два.

Такое дифференцирование может выглядеть следующим образом:

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)
6
ответ дан Michael Anderson 12 дек. '16 в 9:35
источник поделиться

Другие вопросы по меткам