🎃

RubyエンジニアがJavaScriptを書くときに知っておくべきreturnの罠

に公開1

はじめに

RubyからJavaScript(以下JS)に入門するとき、「なぜかfilterやsomeが思ったとおりに動かない」と感じることがあります。

その原因の一つが JavaScriptではreturnを明示的に書かないと値が返らない という仕様です。

この記事では、Rubyエンジニアがつまずきやすいこの点にフォーカスし、JSとの違いと注意点を紹介します。

Rubyでは「最後に評価された値」が返る

Rubyでは、ブロックの最後に評価された値がそのまま戻り値になります。

[1, 2, 3].select do |n|
  n > 1
end
# => [2, 3]

このコードでは、ブロックの最後にn > 1という式があるので、その評価結果(true or false)が自動的に返されます。

JavaScriptでは return がないと返らない

JavaScriptでは、関数の戻り値は明示的にreturnしないと返されません。

[1, 2, 3].filter((n) => {
  n > 1; // returnしていないので undefined を返す
});
// => []

このコードは一見Rubyと同じように見えますが、実はブロック内で値を返していないため、filterはすべての要素を弾いてしまいます。

正しい書き方

明示的にreturnを使う:

[1, 2, 3].filter((n) => {
  return n > 1;
});
// => [2, 3]

あるいは、アロー関数の省略記法を使う:

[1, 2, 3].filter(n => n > 1);
// => [2, 3]

アロー関数でブロック({})を使わなければ、returnは省略可能です。

よくあるパターン:someやfindでも同様
some, find, map, reduceなど、戻り値が重要なメソッドでも同じ注意が必要です。

[1, 2, 3].some((n) => {
  n > 2;
});
// => false(常に undefined を返すため)

// 正しくは
[1, 2, 3].some((n) => {
  return n > 2;
});
// => true

まとめ

項目 Ruby JavaScript
戻り値 ブロックの最後の式 明示的にreturnが必要(※省略記法を除く)
filter, some, など 式を書くだけでOK returnしないと常にfalse扱いになる

おわりに

RubyとJavaScriptの間には細かな文法の違いが多数ありますが、returnの扱いは特に罠になりやすいポイントです。

JSに慣れていないRubyエンジニアは「とりあえずreturn書く」というクセをつけるところからスタートすると、安全に開発を進められるでしょう。

Discussion