web-dev-qa-db-ja.com

ES6 Arrow Functionsで「return」を使用する必要があるのはいつですか?

新しい es6矢印関数 say returnは、いくつかの状況下では暗黙的です:

式は、その関数の暗黙的な戻り値でもあります。

どのような場合にreturnをes6矢印関数で使用する必要がありますか?

128
Jess Telford

ジャクソンは部分的に これに答えました 同様の質問で:

暗黙的に戻りますが、ブロックがない場合のみ。

  • これは、1行が複数行に展開し、プログラマがreturnの追加を忘れるとエラーになります。
  • 暗黙の戻りは構文的にあいまいです。 (name) => {id: name}はオブジェクト{id: name}を返します...そうですか?違う。 undefinedを返します。これらの中括弧は明示的なブロックです。 id:はラベルです。

これに block の定義を追加します。

ブロックステートメント(または他の言語の複合ステートメント)は、0個以上のステートメントをグループ化するために使用されます。ブロックは、中括弧のペアで区切られます。

// returns: undefined
// explanation: an empty block with an implicit return
((name) => {})() 

// returns: 'Hi Jess'
// explanation: no block means implicit return
((name) => 'Hi ' + name)('Jess')

// returns: undefined
// explanation: explicit return required inside block, but is missing.
((name) => {'Hi ' + name})('Jess')

// returns: 'Hi Jess'
// explanation: explicit return in block exists
((name) => {return 'Hi ' + name})('Jess') 

// returns: undefined
// explanation: a block containing a single label. No explicit return.
// more: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/label
((name) => {id: name})('Jess') 

// returns: {id: 'Jess'}
// explanation: implicit return of expression ( ) which evaluates to an object
((name) => ({id: name}))('Jess') 

// returns: {id: 'Jess'}
// explanation: explicit return inside block returns object
((name) => {return {id: name}})('Jess') 
226
Jess Telford

私はこの経験則を理解しています...

効果的に変換される関数(引数の1行操作)の場合、戻り値は暗黙的です。

候補者は次のとおりです。

// square-root 
value => Math.sqrt(value)

// sum
(a,b) => a+b

他の操作(ブロックを必要とする複数のライナーがある場合、戻りは明示的にする必要があります

14
Amarsh

ここには別のケースがあります。

Reactで機能コンポーネントを作成する場合、括弧を使用して暗黙的に返されたJSXをラップできます。

const FunctionalComponent = () => (
  <div>
    <OtherComponent />
  </div>
);
7
Deci

矢印関数を使用すると、暗黙的に返すことができます。値はreturnキーワードを使用せずに返されます。

関数本体にオンラインステートメントがある場合に機能します。

const myFunction = () => 'test'

console.log(myFunction()) //'test'

別の例では、オブジェクトを返します(ラッピング関数の本体ブラケットと見なされないように、括弧で中括弧を囲むことを忘れないでください):

const myFunction = () => ({value: 'test'})

console.log(myFunction()) //{value: 'test'}
3
Flavio Copes

トラブルを起こした別のケースを次に示します。

// the "tricky" way
const wrap = (foo) => (bar) => {
  if (foo === 'foo') return foo + ' ' + bar;
  return 'nofoo ' + bar;
}

ここで、匿名関数を返す関数を定義します。「トリッキー」ビットは、外部関数の関数本体((bar)=> ...で始まる部分)が視覚的に「ブロック」のように見えるが、そうではないことです。そうではないので、暗黙的なリターンが開始されます。

ラップの実行方法は次のとおりです。

// use wrap() to create a function withfoo()
const withfoo = wrap('foo');
// returns: foo bar
console.log(withfoo('bar'));

// use wrap() to create a function withoutfoo()
const withoutfoo = wrap('bar');
// returns: nofoo bar
console.log(withoutfoo('bar'));

私が理解したことを確認するためにこれを展開したのは、関数を「unarrowify」することでした。

これは、最初のコードブロックに相当するセマンティックで、単にwrap()の本体に明示的な戻りを行わせます。この定義では、上記と同じ結果が生成されます。これは、ドットが接続する場所です。上記の最初のコードブロックと以下のコードブロックを比較すると、矢印関数自体が ブロックではなく式であり、暗黙の戻り値を持つ として処理されることが明らかです。

// the explicit return way
const wrap = (foo) => {
  return (bar) => {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  }
}

完全に矢印のないバージョンのラップは、このようになります。これは、太い矢印の付いたバージョンほどコンパクトではありませんが、理解しやすいと思われます。

// the "no arrow functions" way
const wrap = function(foo) {
  return function(bar) {
    if (foo === 'foo') return foo + ' ' + bar;
    return 'nofoo ' + bar;
  };
};

最後に、私のコードを読む必要があるかもしれない他の人、そして将来私のために、私は矢印をかなり取るのではなく、一目で視覚的に理解できる非矢印バージョンに行くことを好むと思いますgrokを考えました(そして私の場合は実験)。

1
grayjohn