CoffeeScript

js->coffee移行にあたって考えたこと

More than 5 years have passed since last update.

個人製作のシステムのjsをcoffeeに完全移行したのでその雑感を書きます。あくまでも個人的な感想です。感じ方は人それぞれです。

ちなみに僕は勉強を兼ねて手で移行させましたが、js2coffeeというツールを使うと自動で変換してくれるらしいです。


先に結論

coffeeの方がいいと思う。

よくある批判に「js書けばいいじゃん」というのがあるけど、極端な話、「アセンブラ書けばいいじゃん」と高級言語が出てきた頃に言ってた人と主張の方向性は似てると思う。極端すぎるけど。

jsには落とし穴がいっぱいある。慣れてもたまにはまる。varを忘れたり「関数の頭で全部のvarを列挙する」というプラクティスに従ってたら、冗長になって管理するコスト高くなったり。

coffeeを使うとそういう余計な問題を意識しなくてよくなるのはとても大きい。

しかもjsでできることの全てをcoffeeでできる。工夫が必要になる場面もあるけど。


coffeeの方がイイ点


データサイズ

もともと19KB程度あったjsファイルをcoffeeで書きなおしたところ、9KBになった。

このことから、普通にjsを書くよりcoffeeを書く方が圧倒的に少ないタイプ量で済むこと分かる。

また、生成されるjsファイルの大きさを見たところ15KBくらいだった。ただし、もとのjsにはドキュメントがついていたことを考えると、それほど大きな差はないと思われる。

ゆえに、jsコードが膨張する心配も無いと僕は結論づけた。


開発スピード

上でも書いたように、タイプ量が減るということは開発スピードが上がることを意味する。

個人開発なので、開発コストは少しでも小さくしたかったので、これは以外と大きいと思った。


クラス

prototypeベースの継承は理解すれば問題無いけれどなんだかんだ言ってクラスベースの方が個人的にしっくりくる。

おれおれクラス実装しているのよく見るけど、ライブラリ毎の微妙な違いとかいちいち考えるの面倒じゃないですか。

coffeeだとclassという専用の構文で書くから、ぱっと見で定義が把握しやすい。


インデント言語

Pythonistaですから


ファイル分けが簡単

即時無名関数内にjsを定義するとプライベート関数とか使えて便利だけど、ソースコードをファイル単位で分割して管理するのがやりにくい。ファイルをまたがって使いたいような関数はグローバルにおかないと行けないから、少なくとも一つはグローバル空間を汚染しないといけなくなる。

// code1

(function() {
this.namespace.hoge = function () {};
// 本当はprivateにしたくても、code2で使うにはグローバルに置かざるをえない
}).call(this);

// code2

(function() {
this.namespace.hoge();
}).call(this);

でもcoffeeならそういう問題がない。

$ cat src/coffee/* | coffee -sp > src/js/main.js

追記:こんなことしなくても、coffeescriptが標準で方法を準備してくれている。http://qiita.com/items/1831

catで結合してからcoffeeに渡すだけでよかったりする。つまり

# code1

hoge ->

# code2

hoge()

catして

# code1

hoge ->
# code2
hoge()

コンパイルすれば以下のようにjsが生成される

(function () {

var hoge;
hoge = function () {};
hoge();
}).call(this);

分かるようにグローバルを汚染すること無くファイルをまたいでプライベート関数を共有できている。

Rails3.1を使ってるとフレームワークの方が同じようなことをしてくれるらしい。

余談:まーjsでもcatでファイルをまたいだプライベートの共有できますけどね。つまり

(function() {

var hoge;

hoge = function () {};

hoge();

}).call(this);

みたいにファイルを分割すれば。でも気持ち悪いことこの上ない。特に最初と最後のファイルが醜悪過ぎる。


学習コスト

今回僕は、coffeeを初めて触った。19KBのjsコードを手で変換するのに2時間弱かかり、その時に調べながらcoffeeへの変換を行った。

jsに関する事前知識が充実していたので、習得が早かったのもあるが、jsを一から勉強するのに比べればcoffeeの学習コストは小さいと感じた。

Pythonistaなのでリスト内包っぽく配列を書けるのが嬉しい。


初学者にはcoffeeの方が優しそう

せっかく書いたから残すけど、あまり重要でないから読み飛ばしてOK

jsには初学者がよく躓く落とし穴が沢山あるが、その際たる例がcallback関数におけるthisの挙動だと思う。

coffeeでは「どんな場面でも=>を使えばよい」という一言でだいたい片が付く。「毎回var self = thisって書いて、thisの代わりにselfを書けばいい」と教えるよりはましだと思う。

for-in文を知った初学者がやりがちな間違いとして、配列をinで回すという失敗もcoffeeなら「配列ならin、オブジェクトならofだよ」で済む。

あとjsでイディオム的に書かれる

for (var prop in obj) if (obj.hasOwnProperty(prop) {

var val = obj[prop]
// doSomething
}

hasOwnPropertyが何故必要か教えるのは面倒だし、タイプ量多くて嫌だけどcoffeeなら

for own prop, val of obj

# doSomething

のように「とりあえずownてつけとけ」で済む。


coffeeの悪い点


書ける人が少ない

現状は。Railsさんの力でこれから先は分からないと思う。

それに学習コストは低いからそれほど問題とは思えない。


jsレベルでのデバッグがしんどい

これが一番問題な気がする。が、自分自身まだ直面したことないからよく分からない


コンパイルが必要

自動化すればいい、というだけの話ではある。