HTML5Experts.jp の altJS に関する記事 http://html5experts.jp/clockmaker/2183/ を読んですこし気になりましたので CoffeeScript で定義された戻り値についてまとめたいと思います。実は今行っているプロジェクトで CoffeeScript 導入を決めたときに、やはり戻り値の話題となりました。CoffeeScript で関数を定義すると基本的には return で何かしら返却するようになっています。
JavaScript の関数
こちらに関しましては「開眼!JavaScript - Cody Lindley著(和田 祐一郎訳) -」を引用したいと思います。
関数(Function()オブジェクト)は、括弧演算子(())で実行することのできるプログラムの入れ物であり、関数は常に値を返します。関数が戻り値を指定しない場合 undefined が返却されます。
これが JavaScript の関数の戻り値に関する定義です。
undefined
やはり「開眼!JavaScript - Cody Lindley著(和田 祐一郎訳) -」の引用ですが、undefined は JavaScript によって2つの異なる方法で使用されます。
- 宣言された変数に値が割り当てられていない
- アスセスしようとしているオブジェクトプロパティが定義されておらず、かつプロトタイプチェンでも見つからない
つまり、関数が戻り値を指定しない場合 undefined が返却されます。これは「値が割り当てられていない」という意味になります。
CoffeeScript の関数
JavaScript の仕様としては基本的に何かしらの戻りを設定しますので CoffeeScript では何も定義せずに戻りを設定するようになっています。
hoge: -> fuga piyo
と定義すると JavaScript に変換された関数は、先ほど関数は「常に戻り値を返します」としたので CoffeeScript が戻り値を補完してくれます
({ hoge: function() { fuga; return piyo; } });
暗黙的に最後に定義した piyo を戻り値として補完しています。実装者として、この piyo 戻りは意味がない場合もあり、単純にオブジェクト this を返却したい場合には
hoge: -> fuga piyo this
と記載します。JavaScript では
({ hoge: function() { fuga; piyo; return this; } });
と成ります。this の代わりに @ も使えますが、私は戻りを定義する場合には this を使用してます。
一般的なルール(JavaScript の関数の定義)として、定義した関数において「何を返却するのか」は明示的に記述すべきことです。この関数が何を受け入れ何を返却するのかが重要になります。指定しなかった場合 CoffeeScript では最後に出現したものを返却してくれます。
hoge: -> // この関数にどんな引数を渡すのかを定義 ・・・ this // 何を返却するのか定義
とは言っても返却する値が見つからない場合
返却する場合が無い場合「ありません」を明示的に示す必要があります
hoge: -> fuga piyo return
JavaScript では
({ hoge: function() { fuga; piyo; } });
となり、これは関数が戻り値を指定しない場合の例で関数の戻り値が undefined となるということ定義しています。
では undefined を明示的に返却した場合どうでしょうか?CoffeeScript では
hoge: -> fuga piyo return undefined
JavaScript では
({ hoge: function() { fuga; piyo; return void 0; } });
となります。void は常に undefined を返す演算子です。これも CoffeeScript が 補完してくれていて undefined を void に再定義してくれてます。undefined を使わない理由としては、定義された undefined はただのグローバル変数であり、この undefined が本当の undefined であり続ける保証が無いためです。
まとめ
CoffeeScript で基本的に return を補完している理由として JavaScript の言語仕様で「関数は常に値を返します」ということがあるためです。