ES6 / Typescriptの矢印関数での_(アンダースコア)変数の使用


119

私はAngularの例でこの構造に出くわし、なぜこれが選択されるのか不思議に思います:

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

変数_は気にしない/使用しないことを意味しますが、それが唯一の変数であるため、_よりも_の使用を好む理由があります。

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

確かに、これはタイプするのに約1文字少なくなることはありません。()構文は、私の考えでは意図をよりよく伝え、タイプ固有でもあります。それ以外の場合、最初の例は次のようになっているはずだと思います。

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

重要な場合は、これが使用されたコンテキストです。

submit(query: string): void {
    this.router.navigate(['search'], { queryParams: { query: query } })
      .then(_ => this.search());
}


1
決して使用されないパラメーターのタイプやタイプの特異性をどうやって心配することができますか?

3
私は貿易によってC ++開発者なので、型の特定性について常に心配しています:-)。
2016

6
個人的には、_ =>パターンは括弧の数を減らし、読みやすくします:doStuff()。then(()=> action())とdoStuff()。then(_ => action())。
Damien Golding

回答:


93

このスタイルを使用できる理由(およびここで使用された可能性がある理由)は、_よりも1文字短いため()です。

オプションの括弧は、オプションの波括弧と同じスタイルの問題に分類されます。これは、ほとんどの場合、好みとコードスタイルの問題ですが、一貫性があるため、ここでは冗長性を優先します。

矢印関数は括弧なしの単一のパラメーターを許可しますが、ゼロ、単一の非構造化、単一の休息、および複数のパラメーターと矛盾します。

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

is declared but never usedエラーが活字体2.0に固定した下線パラメータについて、_また、トリガできunused variable/parameterリンターまたはIDEからの警告。これは、これを行うことに対するかなりの議論です。

_従来は無視されたパラメータに使用できます(他の回答はすでに説明しています)。これは許容できると考えられますが、この習慣は_Underscore / Lodash名前空間との競合を引き起こす可能性があり、無視されたパラメーターが複数ある場合も混乱します。このため、適切に名前が付けられた下線付きパラメーター(TS 2.0でサポート)を使用すると、関数のシグネチャを特定する時間を節約でき、パラメーターが無視されているとマークされる理由も短縮されます(これは_パラメーターのショートカットとしての目的に反します)。

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

上記の理由から、私は個人的に_ => { ... }コードスタイルを回避すべき悪い調子だと考えます。


1
1文字短いですが、(通常はが付いているので、ほとんどのIDEで同じ量のキーを押し)ます。私は個人的にpforパラメータを使用することを好み ますが、パフォーマンスの問題があるかどうかも疑問に思います
Mojimi

68

()構文は意図より良い私見を伝え、また、より多くの種類の特定です

ではない正確に。()関数は引数を期待しないと言い、パラメータを宣言しません。関数の.lengthは0です。

を使用する場合_、関数には1つの引数が渡されることを明示的に示しますが、それは問題ではありません。関数.lengthは1になります。これは、一部のフレームワークでは問題になる可能性があります。

そのため、タイプの観点からすると、(特に、タイプしないでany、たとえばと入力する場合は)より正確な場合があります_: Event。そして、あなたが言ったように、それはタイプするよりも1文字少ないので、一部のキーボードでも到達しやすくなります。


6
私の最初の考えは、_は関数を理解しようとするときに考慮すべき引数がないことを慣例によってのみ明らかにすることでした。()を使用すると明示的になります。_を使用できるかどうかコードをスキャンする必要はありません(これは規則に違反します)。しかし、あなたは私の目を開いて、関数に渡される値があることを文書化することの価値についても検討しました。
停止

私のコードが未使用_のsアロー関数変数でいっぱいであることに気づきました。使用と比較してパフォーマンスに違いがあるの()
でしょ

24

JSのようにパラメーターを省略することが許可されていない他の言語では一般的であるため、_ =>単に使用されて() =>いると思い_ます。

_ Goで人気があり、Dartでもパラメーターが無視されていることを示すために使用されています。


4
Pythonもこの規則に従っていると思います。
Jaime RGP 2016

7
このの使用法は、_おそらくMLやHaskellなどの関数型言語から借用されたものであり、Python(Go、Dart、TypeScriptはもちろん)の発明よりもずっと以前から使用されていました。
ruakh 16

1
Rubyもそれを行い(po-ru.com/diary/rubys-magic-underscore)、F#も(MLファミリーの影響を受ける他の言語も)
Mariusz Pawelski

Scalaはアンダースコアが大好きです(includehelp.com/scala/use-of-underscore-in-scala.aspx)。Scalaが下線付きの匿名型で何をしているかに続いて、どの言語が採用されましたか。
Sam

Scalaも他の言語から採用したと思います。70年代にはまだ存在していなかったプログラミング言語にはほとんどありません:Dほとんどのものを組み合わせる新しい方法だけです。
ギュンターZöchbauer

11

2つの使用法を区別することは可能であり、一部のフレームワークはこれを使用して異なるタイプのコールバックを表します。たとえば、ノードエクスプレスフレームワークはこれを使用してミドルウェアのタイプを区別すると思います。たとえば、エラーハンドラーは3つの引数を使用し、ルーティングは2つの引数を使用します。

このような区別は、以下の例のようになります。

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);


1
これは、Bergiの回答に基づいていますが、例を追加することは、他の誰かの投稿に対して喜んで行うよりも少し編集することだと思いました。
Michael Anderson、

0

私が投稿を書いたとき、を_使わず()にアロー関数を作成する唯一の方法であるという印象を受けまし_た。@Haltは、他の変数と同じように動作することをコメントで確認しました。これは特別な言語構成ではありません。


どこにも言及されていないことを自分でテストしながら、これらの下線付き矢印関数について私が認識したもう1つのことを述べたいと思います。あなたはできるパラメータとしての機能にアンダースコアを使用し、未使用のパラメータを表すことになっていますので、これはおそらく、使用を意図していないものの、。わかりやすくするために、この方法で実際に使用することはお勧めしません。しかし、codegolfのようなもの、あなたが最も短いコードを書くところの挑戦について知ることは役に立つかもしれません(なしで任意の文字を使用できることが())ライブラリがこれを使用する実際のユースケースを想像できますが、その機能を意図していなくても使用する必要があります。

例:

// simple number doubling function
f = _=> {
    _ = _ * 2;
    return _;
}

console.log(f(2)); // returns 4
console.log(f(10)); // returns 20

Chromeコンソールでテスト済み、バージョン76.0.3809.132(公式ビルド)(64ビット)


1
アンダースコア「_」は正当な変数名であり、特別な言語構成ではなく、慣例により特別な意味が与えられているだけです。未使用のパラメーターに関するリンター警告は、アンダースコアプレフィックスを使用して沈黙させることができます。_自体は、未使用と言う最も短い方法だと思います。
停止

@Halt明確にしていただきありがとうございます。()この投稿をする前に、アロー関数なしでアロー関数を作成できることに実際には気づかなかったので_、これが唯一の方法だと思ったので、これを指摘することにしました。これを念頭に置くと、通常のキャラクターだけを使用できるため、ゴルフをする場合でも特別なことは何もありません。あなたが言ったように、次の規則のために単によりよく使われます。
Matsyir
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.