hubotで遊ぶ時に、coffeescriptを触ってみました。このきっかけで、coffeescriptについてちょっと紹介したいと思います。

CoffeeScriptとは?

CoffeeScriptを一言で言えば、JavaScriptがシンプル化した言語です。しかし、CoffeeScriptが直接ブラウザやnode.jsでは実行できません。JavaScriptにコンパイルしなければなりません。なので、CoffeeScriptはJavaScriptを書く効率を上げるための言語です

CoffeeScriptの必要性?

CoffeeScriptはRubyやPythonなどを参考していて、今風の文法で結構書きやすいです。その上、JavaScriptのややこしいところ(classのコンセプトがないとか)を補完しています。

しかし、CoffeeScriptはsassみたいに、コンパイルしないとほぼ意味ないので、「JavaScript書けるから、何でCoffeeScriptで書かないといけないの?」とかいう方もいるだろうし(自分はそうだった)。チームワークになると、みんなCoffeeScriptを勉強しなければならないし、なかなか難しいところです。

基本文法

CoffeeScriptは自分の文法を持っていますが、JavaScriptの文法もすべて使えますCoffeeScriptにはタブ記号がサポートされてなく、すべてスペースに変換しないとうまくコンパイルされないので、エディターの設定をチェックしましょう。

コメント

# これはコメントです
###
	複数行のコメントはこう。。
	...
###

変数

CoffeeScriptで変数を定義するには、JavaScriptのvarはいらないです

apple = 'りんご'

CoffeeScriptはグロバール変数を廃棄しました。もしどうしても使いたい場合は、ルートスコープで下記のように、変数を宣言します:

glob = this
glob.banana = 'グロバールのバナナ'

すると、glob.bananaがグローバル変数と同じ機能します。

関数

JavaScriptのfunctionは、CoffeeScriptで非常にシンプルになりました。

# CoffeeScript
say = (something) -> console.log(something)
say "hello, world"

# JavaScript
var say = function(something){
	console.log(something)
}
say("hello, world");

もしfunctionの引数がない場合は、省略できます:

say = -> "hello"

これをJavaScriptで解釈すると:

var say = function() {
	return "hello";
}

コンディション

fruit = 'apple'
eat = (fruit) -> console.log('eat ' + fruit)

if fruit is 'apple'
	eat fruit
	

CoffeeScriptは===!==の代わりにisisntを使っています。==!=はあまりおすすめしません(もちろん、使えますが)。そして、否定の!はCoffeeScriptでnotというアリアスも使います。

if fruit is not 'pear'
	eat fruit

上記の文を一行で完結したければ、thenを使います。

if fruit is 'apple' then eat fruit

if fruit is not 'pear'
	eat fruit

CoffeeScriptはRubyみたいに、ifは後ろ置きでもできます。

eat fruit if fruit is 'apple'

unlessも使えます(if notと同じ意味)

eat fruit unless fruit is 'pear'

ループ

CoffeeScriptは素晴らしいイテレータがあります。例えば:

for fruit in ['apple', 'bananer', 'pear']
	console.log fruit

もっとシンプルすると:

console.log fruit for fruit in ['apple', 'bananer', 'pear']

とも書ける。パッと見ると、わけわからないかもしれないが。読むときは、右から読めばわかりやすいです、まず

for fruit in ['apple', 'bananer', 'pear']

['apple', 'bananer', 'pear']中の要素を一つずつ抽出し、fruitに保存し、console.log(fruit)に渡します。

もしインデックスを取得したければ

for fruit, index in ['apple', 'bananer', 'pear']
	console.log index + ' ' + fruit

ハッシュタイプの配列のイテレータも簡単!

player = {
	hp : 100,
	mp : 100,
	attack : 120,
	defence : 80
}

for param, value in player
	console.log('param: ' + value )

OOP

CoffeeScript一番便利なところは、はっきりしたclassのコンセプトがあるところです。JavaScriptにclassというものはないだが、classらしいものが作れます。たとえば:

var Player = function Player(name)
{
	this.name = name;
}

このPlayerがJavaScriptのclassになります。

CoffeeScriptだと、もっと「きれい」な書き方ができます。

class Player
	constructor: (name) ->
		@name = name

constructorの中に@をつければ、クラスのメンバー変数になります。

player = new Player('Bii')
console.log(player.name) # Bii

同じ感じで、メソードを追加します。

class Player
	sayHello : =>
		console.log('こんにちは')
	constructor: (name) ->
		@name = name
 
player = new Player('Bii')
player.sayHello() # こんにちは

staticメンバーは、classのスコープで@を付けて定義します。

class Player
	@find : (name) -> # これがスタティックメンバー
		console.log("Searhing user #{name}") 		

	constructor: (name) ->
		@name = name #これがメンバー変数
Player.find('Bii') # Searhing user Bii

@はJSでというとthisと似てます。なので、スコープによって意味が変わるので、要注意です。@constructorのスコープではメンバー変数になりますが、classスコープではスタティックメンバーになります。

まとめ

CoffeeScriptは非常に使いやすくて、効率も良いし、コンパイルすれば純正のJavaScriptになるので、互換性にも心配ありません。もちらん、CoffeeScriptに慣れちゃったら、普通のJSが書けなくなってしまう可能性もあります。例えば、var;を忘れたりするとかもあり得ることです。なので、JavaScriptをマスターしてから、CoffeeScriptを書くのをおすすめします。