はじめるCoffeeScript その3

2012.06.30

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

うえじゅんです。

さらに前回からの続きです。
今回も「TRY COFFEESCRIPT」で動作できるサンプルで進めていきます。

class

クラスもシンプルに書くことができます。
プロパティやメソッドもわかりやすくJavaScriptに比べて可読性が高いと思います。

CoffeeScript

class Momokuro
  constructor: (@name) ->

  weekend: (word) ->
    console.log word + " " + @name

momoiro = new Momokuro "ももいろクローバーZ"

momoiro.weekend "週末ヒロイン"

クラスの継承もできます。

CoffeeScript

class Momokuro
  constructor: (@name) ->

  catchphrase: (phrase) ->
    console.log @name + " : " + "phrase"

class Red extends Momokuro
  catchphrase: ->
    console.log "Red"
    super "茶畑のシンデレラ"

class Yellow extends Momokuro
  catchphrase: ->
    console.log "Yellow"
    super "みんなの妹"

class Pink extends Momokuro
  catchphrase: ->
    console.log "Pink"
    super "ももクロのアイドル"

class Green extends Momokuro
  catchphrase: ->
    console.log "Green"
    super "小さな巨人"

class Purple extends Momokuro
  catchphrase: ->
    console.log "Purple"
    super "感電少女"

kanako = new Red "百田夏菜子"
shiori = new Yellow "玉井詩織"
ayaka  = new Pink "佐々木彩夏"
momoka = new Green "有安杏果"
reni   = new Purple "高城れに"

kanako.catchphrase()
shiori.catchphrase()
ayaka.catchphrase()
momoka.catchphrase()
reni.catchphrase()

JavaScriptより書きやすいのではないでしょうか。

一歩踏み込んで実際に"Backbone.js"を利用した際の例を見てみましょう。
JavaScriptとCoffeeScriptで書いたものを比べられるようにしてみました。

JavaScript(コードはHello Backbone.js Tutorialからの引用です)

(function($){
  Backbone.sync = function(method, model, success, error){ 
    success();
  }

  var Item = Backbone.Model.extend({
    defaults: {
      part1: 'hello',
      part2: 'world'
    }
  });
  
  var List = Backbone.Collection.extend({
    model: Item
  });

  var ItemView = Backbone.View.extend({
    tagName: 'li', // name of tag to be created

    events: { 
      'click span.swap':  'swap',
      'click span.delete': 'remove'
    },

    initialize: function(){
      _.bindAll(this, 'render', 'unrender', 'swap', 'remove'); // every function that uses 'this' as the current object should be in here

      this.model.bind('change', this.render);
      this.model.bind('remove', this.unrender);
    },

    render: function(){
      $(this.el).html('<span style="color:black;">'+this.model.get('part1')+' '+this.model.get('part2')+'</span>     <span class="swap" style="font-family:sans-serif; color:blue; cursor:pointer;">[swap]</span> <span class="delete" style="cursor:pointer; color:red; font-family:sans-serif;">[delete]</span>');
      return this; // for chainable calls, like .render().el
    },

    unrender: function(){
      $(this.el).remove();
    },

    swap: function(){
      var swapped = {
        part1: this.model.get('part2'), 
        part2: this.model.get('part1')
      };
      this.model.set(swapped);
    },

    remove: function(){
      this.model.destroy();
    }
  });

  var ListView = Backbone.View.extend({
    el: $('body'), // el attaches to existing element
    events: {
      'click button#add': 'addItem'
    },
    initialize: function(){
      _.bindAll(this, 'render', 'addItem', 'appendItem'); // every function that uses 'this' as the current object should be in here
      
      this.collection = new List();
      this.collection.bind('add', this.appendItem); // collection event binder

      this.counter = 0;
      this.render();
    },
    render: function(){
      var self = this;
      $(this.el).append("<button id='add'>Add list item</button>");
      $(this.el).append("<ul></ul>");
      _(this.collection.models).each(function(item){ // in case collection is not empty
        self.appendItem(item);
      }, this);
    },
    addItem: function(){
      this.counter++;
      var item = new Item();
      item.set({
        part2: item.get('part2') + this.counter // modify item defaults
      });
      this.collection.add(item);
    },
    appendItem: function(item){
      var itemView = new ItemView({
        model: item
      });
      $('ul', this.el).append(itemView.render().el);
    }
  });

  var listView = new ListView();
})(jQuery);

CoffeeScript(コードはCoffeeScript, Meet Backbone.js: A Tutorialからの引用です)

jQuery ->
  
  class Item extends Backbone.Model
    
    defaults:
      part1: 'Hello'
      part2: 'Backbone'

  class List extends Backbone.Collection
    
    model: Item

  class ItemView extends Backbone.View

    tagName: 'li'

    initialize: ->
      _.bindAll @
      
      @model.bind 'change', @render
      @model.bind 'remove', @unrender

    render: =>
      $(@el).html """
        <span>#{@model.get 'part1'} #{@model.get 'part2'}!</span>
        <span class="swap">swap</span>
        <span class="delete">delete</span>
      """
      @

    unrender: =>
      $(@el).remove()

    swap: ->
      @model.set
        part1: @model.get 'part2'
        part2: @model.get 'part1'

    remove: -> @model.destroy()

    events:
      'click .swap': 'swap'
      'click .delete': 'remove'

  class ListView extends Backbone.View

    el: $ 'body'
    
    initialize: ->
      _.bindAll @
      
      @collection = new List
      @collection.bind 'add', @appendItem
      
      @counter = 0
      @render()
    
    render: ->
      $(@el).append '<button>Add Item List</button>'
      $(@el).append '<ul></ul>'
    
    addItem: ->
      @counter++
      item = new Item
      item.set part2: "#{item.get 'part2'} #{@counter}"
      @collection.add item
    
    appendItem: (item) ->
      item_view = new ItemView model: item
      $('ul').append item_view.render().el
    
    events: 'click button': 'addItem'

  Backbone.sync = (method, model, success, error) ->
    success()

  list_view = new ListView

いかがでしょうか。
CoffeeScriptの方がシンプルかつ読みやすいと感じるのではないでしょうか。

それでは今回はここまでにします。
次回は「TRY COFFEESCRIPT」でお手軽な確認を終え、環境構築について進めて行きたいと思います。