Takazudo hamalog

programming notes. mainly about JavaScript / jQuery. [@Takazudo] [takazudo@gmail.com] Hint: alt + /

cool guy

CoffeeScriptいいかも

2012/02/15 permalink

存在は知ってたけどさっぱり興味のわかなかったCoffeeScriptなのですが、使ってみたらこれいいかもって思って、というかもうこれからはCoffeeScriptで書いていこうかなと思いだしてる中。CoffeeScriptが何かについては、以下を参照のこと。

きっかけは JavaScript Web Applications という本を読んで、この本書いてる人が作ってる Spine というフレームワークを見てみようかなーと、見始めたら、なんかこのSpine自体がCoffeeScriptで書かれてた。そんで、ドキュメントを読んでいこうと思ったら、「まーCoffeeScriptでやらんでもいいけどさ、JS書いてる人はちょっくら見てみる価値はあるぜー」みたいなことが書いてあった。ので、「はーめんどくさいけど郷に入りては郷にうんたらだからちょっとだけ見てみるかー」とか思い、やってみたら、あれ?これなんかめちゃくちゃよくないですか?と思い、ちょっと書いてみているところで、結果Spineはまだ見れてない。

CoffeeScriptが、短く、エレガントに書けるってのはもちろん見りゃぁ分かるレベルでして、そりゃー素敵ですなーって思うものの、うーんそれでも導入するか?という感想でした。でも、これは使いたい…と、自分が特に気に入ったのが以下。

例えば、こんなUI を作りますーっていう時、自分は大体クラス的なものを作って、メソッドをポコポコ生やして、こんな感じにする。

var SomeUI = function($el) {
    this.$el = $el;
    this.$content = $el.find('.content');
    this.$button1 = $el.find('.button1');
    this.$button2 = $el.find('.button2');
    this._eventify();
};
SomeUI.prototype._eventify = function() {
    this.$button1.click($.proxy(function(){
        this.instantToggle();
    }, this));
    this.$button2.click($.proxy(function(){
        return this.delayedToggle();
    }, this));
    return this;
};
SomeUI.prototype.instantToggle = function() {
    this.$content.fadeToggle();
    return this;
};
SomeUI.prototype.delayedToggle = function() {
    setTimeout($.proxy(function(){
        this.$content.fadeToggle();
    }, this), 1000);
    return this;
};

$.fn.someUI = function() {
    return this.each(function() {
        new SomeUI($(this));
    });
};

$(function() {
    return $('.someUI').someUI();
});

このコードの中で、毎度毎度めんどくさいのが $.proxy の部分。ここ、こうしない場合は、var self = this; だとか、var _this = this; だとかやっているものとみんな思われる。メソッドを作るたびに、嗚呼、イベントハンドラなりsetTimeoutきたからvar self = this; しなきゃとか、そのたびにちょっと置換したりとか。jQueryの $.proxy はあるけど、なんか長いし分かりづらそうだし、ウームみたいな。上記コードを、CoffeeScriptを使って書けば、以下のように出来る。

class SomeUI
  constructor: ($el) ->
    @$el = $el
    @$content = $el.find '.content'
    @$button1 = $el.find '.button1'
    @$button2 = $el.find '.button2'
    @_eventify()
  _eventify: ->
    @$button1.click =>
      @instantToggle()
    @$button2.click =>
      @delayedToggle()
    @
  instantToggle: ->
    @$content.fadeToggle()
    @
  delayedToggle: ->
    setTimeout ( =>
      @$content.fadeToggle()
    ), 1000
    @

$.fn.someUI = ->
  @each ->
    new SomeUI $(@)

$ ->
  $('.someUI').someUI()

$.proxyだのbindだの、そういう部分は、=> って書くだけでOK。勝手に $.proxy的なことしてくれる。そんな self = thisだのを山のように書いていた身からすると、こう書きたかったですよ!っていう感じだ。あとは、CoffeeScript上ではフツーにクラスがあるので、もうなんかJSにはクラスがねーんだとかあるんだとか、やるんだったらどういう風にやるとか、そういうのはもう忘れておいていいですね。

あとは、thisも@で済ませるのでこれもめちゃ楽チン。そんでもって、ifの中でvar hoge = … とか書くにしても、ああこれってメソッドの頭で変数宣言しておいたほうがいいよね…でもまぁいっかみたいな。そういう時も、CoffeeScriptなら、そもそもvarとかで宣言しなくても勝手にスコープの頭にvar 変数 って感じで追加してくれるので楽。

上記みたいにCoffeeScriptを書いたら、

  • coffeeコマンドでjsに変換する
  • ページにCoffeeScriptのコンパイルスクリプトを読み込ませ、type=”text/coffeescript” でCoffeeScriptを読み込み、その場でブラウザにコンパイルさせる

のどっちかをやる。まぁ、フツーに使う場合には前者だと思う。ちなみに後者でやってみたのがコレ

使う前に心配だったのが、エラーとか追跡しづらそうだなーということなんだけれども、コレ、確かに後者の方法だとエラーは追いづらいものの、フツーにコンパイルしたものであれば、かなり素直なコードになってくれるので、多分そういう心配はあんまりいらなそう。上記をコンパイルした結果がコレ。なんか普通に人が書いたみたいに綺麗ですよね…。

そんでもって自動でファイルが更新されたらコンパイルしてくれたりとかもできるので、普段からコレで書くのもかなりアリなんじゃないかなーって思い中。気になる方は、コレを通して読みつつ写経でもするとよさそうです。自分はした。

あと、vimを使っている方は、シンタックスハイライトだの、リアルタイムコンパイルプレビューだの、便利機能が詰まっているものを配布していくれている人がいるので、コレを入れるとそれだけで環境がバッチシ整ってしまいます。

今日もちょっと、実際に仕事的に使うようなものを書いてみたらどうだろうかと、書いてみました(htmlcoffee)けども、CoffeeScriptで書くのはかなり楽しいですね。自動コンパイルと同時に yuicompressor かけるとかも、Cakefile とかいうものを作って実行させておけばできちゃったりするっぽいですよ。

ただ、JS書き始めて勉強中ですとか、まーちょっと書くだけなんですよとかいう場合には、あんまりおすすめではないかも。導入もやや面倒ですし、CoffeeScriptを書きながらも出来上がりのJSをイメージしなければならないため。ただ、普段からじゃかじゃかJS書く人にとっては、ちょっと触ってみるだけでも、CoffeeScriptがやってくれることの素晴らしさを体感できるものと思われます。

blog comments powered by Disqus

  1. saitamanodoruji4saitamanodorujiからリブログしました
  2. makotoishidahamalogからリブログしました
  3. ken0205syoichiからリブログしました
  4. nullpointerexceptionsyoichiからリブログしました
  5. cyborgninjasyoichiからリブログしました
  6. srggnsbrglolicsystemからリブログしました
  7. xxxdfloorxxxsyoichiからリブログしました
  8. hanwaraisaitamanodorujiからリブログしました
  9. ukarsaitamanodorujiからリブログしました
  10. blasnosaitamanodorujiからリブログしました
  11. xiuxing-webh2ospaceからリブログしました
  12. saitamanodorujisyoichiからリブログしました
  13. knnrsyoichiからリブログしました
  14. himatbshizsyoichiからリブログしました
  15. daikantousyoichiからリブログしました
  16. takkyun1019syoichiからリブログしました
  17. kazzxzsyoichiからリブログしました
  18. tmftakesyoichiからリブログしました
  19. hiroakisnobby0-0からリブログしました
  20. syutasyoichiからリブログしました
  21. kuranosyoichiからリブログしました
  22. nobby0-0syoichiからリブログしました
  23. abukusyoichiからリブログしました
  24. atm09tdhamalogからリブログしました
  25. meruna8interglacialからリブログしました
  26. interglacialsyoichiからリブログしました
  27. syamojisyoichiからリブログしました
  28. kitatubasyoichiからリブログしました
  29. firebumsyoichiからリブログしました
  30. orihikasyoichiからリブログしました
  31. sh19910711syoichiからリブログしました