CoffeeScriptを使う理由

随時更新します。

1. [CoffeeScriptを使う理由](http://qiita.com/asaake88/items/9462844b049900ffb22c)
2. [TypeScriptを使う理由](http://qiita.com/asaake88/items/a0f17d9f4f757d88a83a)
3. AltJSを使わない理由
4. Dartを使う理由

仕事でCoffeeScriptを使う場合の説得材料まとめです。

# なぜJavaScriptではいけないのか

## クラス定義がないからです

みんな大好きオブジェクト指向をするために必須なのにJavaScriptではクラスは書けません。
いや、正確には書けます。

```js:クラス定義
function Person() {};
```

なんだクラスは簡単に書けるじゃないかと思いましたか？

---

```js:クラス定義その２
function Person() {
  this.name = "takashi";
  this.age = 20;
};
Person.prototype.echo = function () {
  return "Hello " + this.name + " !!";
};
```

コンストラクタ、メソッドを書いただけで、コード量が増えてきましたね。
毎回クラス名とprototypeと書く必要があります。
めげてきましたか？
私はめげてます。

---

次は継承してみましょう。

```js:継承
function inherits(ctor, superCtor) {
  ctor.super = superCtor;
  ctor.prototype = Object.create(superCtor.prototype, {
    constructor: {
      value: ctor,
      enumerable: false,
      writable: true,
      configurable: true
    }
  });
};

inherits(Employee, Person);
function Employee() {
  Person.apply(this, arguments);
};

Employee.prototype.echo = function () {
  return "Hello " + Employee.super.prototype.echo.call(this);
};
```

どうでしょうか？
継承元を呼び出すのにEmployee.super.prototype.echo.call(this)のように書かないといけません。

継承の方法は今まで迷走していたので各々実装方法も違います。
詳しく知りたい場合はこちらを参照するといいです。
[そんな継承はイヤだ - クラス定義 - オブジェクト作成](http://qiita.com/LightSpeedC/items/d307d809ecf2710bd957)

## 勘違いしてしまうfor文

以下のコードは間違っています。

```js:間違ったfor...in
var ary = [100, 200, 300];
for (var i in ary) {
  console.log(i);
}
```

JavaScriptでinは配列のeachではありません。
オブジェクトのプロパティ名をeachする命令です。

```js:正しいfor...in
var obj = {key1: 100, key2: 200, key3: 300}
for (var key in obj) {
  console.log(obj[key]);
}
```

```js:正しい配列のfor
var ary = [100, 200, 300];
for (var i = 0 ; i < ary.length ; i++) {
  console.log(ary[i]);
}
```

## functionという記述が長過ぎる

JavaScriptはシングルスレッドなので、callbackを多用します。
多用するのに毎回functionと書かなければいけません。
後からコードを見直すとfunctionだらけで頭が痛くなることでしょう。

```js:functionが長過ぎる
var self = this;
$.get("/users", function (users) {
  var result = [];
  $.each(users, function (user) {
    result.push(new User(user));
  });
  return result;
}).done(function (users) {
  self.users = users;
}).fail(function (xhr, status, msg) {
  console.error(msg);
});
```

## グローバル汚染を防ぐためにすることがある

functionで命令を閉じ込めてあげないとグローバルに定義されるので
他のライブラリとぶつかったりします。

varを書き忘れるとグローバルになるので他のライブラリと・・・

```js:グローバル汚染をする？しない？
// グローバル汚染します
function Person() { // グローバル汚染
  name = "takashi"; // グローバル汚染
  this.word = "Hello " + name + " !!"; // でも動くよ
}
new Person();
name; // -> takashi

// グローバル汚染しません
(function () {
  function Person() {
    var name = "takashi";
    this.word = "Hello " + name + " !!";
  }
  new Person();
})();
name; // undefined
```

## 比較が曖昧

比較時に勝手に変換すると予期せぬ挙動となります。
なので毎回===と書かなくてはいけない。

```js:比較例
""           ==   "0"           // false
0            ==   ""            // true
0            ==   "0"           // true
false        ==   "false"       // false
false        ==   "0"           // true
false        ==   undefined     // false
false        ==   null          // false
null         ==   undefined     // true
" \t\r\n"    ==   0             // true
```

# CoffeeScriptを使おう

これらのよくないコードを未然に防いでくれるのがCoffeeScriptです。
それぞれ例をみていきましょう。

```coffeescript:クラス定義
class Person
  constructor: () ->
    @name = "takashi"
    @age = 20

  echo: () ->
    "Hello #{@name} !!"

class Employee extends Person
  constructor: () ->
    super

  echo: () ->
    "Hello #{super()}"
```
```coffeescript:for文
# 配列のループ
ary = [100, 200, 300]
for value in ary
  console.log value

# プロパティのループ
obj = {key1: 100, key2: 200, key3: 300}
for key, value of obj
  console.log(value)
```

```coffeescript:function文
$.get "/users", (users) =>
  result = [];
  $.each users, (user) =>
    result.push(new User(user))
  return result
.done (users) =>
  @users = users
.fail xhr, status, msg =>
  console.error(msg)
```

```coffeescript:グローバル汚染しない
# CoffeeScriptコンパイル時にbare=trueで関数で囲んでくれる
class Person
  constructor: () ->
    @name = "takashi" # インスタンス変数
    @word = "Hello #{name} !!" # ローカル変数
}
new Person()
name # -> undefined
```

```coffeescript:比較は厳密
""           ==   "0"           # false
0            ==   ""            # false
0            ==   "0"           # false
false        ==   "false"       # false
false        ==   "0"           # false
false        ==   undefined     # false
false        ==   null          # false
null         ==   undefined     # false
" \t\r\n"    ==   0             # false
```

どうですか？
ダメなコードも未然に防げて、かつ簡素なコードでしょう？

# CoffeeScriptはコンパイルしてJavaScriptを出力するけど、デバッグはどうするの？

CoffeeScriptにはSourceMapを出力するオプションが存在します。
これは出力されたJavaScriptがCoffeeScriptのどのコードの位置とマッチするかの情報を含んだファイルです。
これをChromeに食わせることにより、CoffeeScriptでデバッグが行えます。

詳しいやり方はグーグルで`CoffeeScript source map chrome`とかで検索するといいです。

ですが私が今までCoffeeScriptで開発してきた経験からいうと、出力されたJavaScriptをそのままデバッグした方が楽にデバッグできます。

CoffeeScriptが何行かのJavaScriptを出力しているために、同じ行でデバッガーのNext Stepを何回する必要があるため、変なところで進んだり止まったりしてデバッグしにくいです。

consoleにそのままCoffeeScriptを貼付けて動作させることもできないので、わざわざ変換するのが面倒だったりします。
CoffeeConsole？あれは忘れた方がいい。

CoffeeScriptは別言語なのではなく、JavaScriptのシンタックスシュガーです。
CoffeeScriptとJavaScriptの命令は1対1で簡単に結びつきます。
なので出力されたJavaScriptで苦もなくデバッグすることができます。

# ちょっと注意、魔法の杖ではありませんよ。
HibernateしかりActiveRecordしかり、ORMはDBの設計、SQLをある程度知っていて始めて使用することができます。
ORM使うからSQL知らなくても問題ないぜー！！バリバリー！！
みたいなことはしてませんよね？

CoffeeScriptもご多分に漏れずJavaScriptをある程度知っている必要があります。
いきなりCoffeeScriptから始めます！
というようなことは避けた方が懸命です。
JavaScriptを軽く学習させてからCoffeeScriptを学習させてください。
そうしないとデバッグで死にます。

# わかりました。CoffeeScriptを使います。

ようこそCoffeeScriptの世界へ。

あたなはCoffeeScriptを採用したことで以下の恩恵を受けることができます。

1. ソースコードが簡素になったことで保守性があがります。
2. JavaScriptの罠に嵌らなくなります。

あれ？少ない？
いえいえ、すごく大事な２点です。
塵積です。

# でも待って・・・実は問題山積みなんです。

CoffeeScriptはコンパイルが必要です。
このコンパイルを甘く見てはいけません。

やってみればわかります。めんどいです。

私もCoffeeScriptコンパイルジプシーです。

・・・この投稿はとりあえずここまで！！
次回私が行ったCoffeeScriptのコンパイル方法の変遷を紹介します。

書きました。
[私のCoffeeScriptをコンパイルする方法の変遷](http://qiita.com/asaake88/items/3586fb494bc5446a7995)