随時更新します。
- CoffeeScriptを使う理由
- TypeScriptを使う理由
- AltJSを使わない理由
- Dartを使う理由
仕事でCoffeeScriptを使う場合の説得材料まとめです。
なぜJavaScriptではいけないのか
クラス定義がないからです
みんな大好きオブジェクト指向をするために必須なのにJavaScriptではクラスは書けません。
いや、正確には書けます。
function Person() {};
なんだクラスは簡単に書けるじゃないかと思いましたか?
function Person() {
this.name = "takashi";
this.age = 20;
};
Person.prototype.echo = function () {
return "Hello " + this.name + " !!";
};
コンストラクタ、メソッドを書いただけで、コード量が増えてきましたね。
毎回クラス名とprototypeと書く必要があります。
めげてきましたか?
私はめげてます。
次は継承してみましょう。
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)のように書かないといけません。
継承の方法は今まで迷走していたので各々実装方法も違います。
詳しく知りたい場合はこちらを参照するといいです。
そんな継承はイヤだ - クラス定義 - オブジェクト作成
勘違いしてしまうfor文
以下のコードは間違っています。
var ary = [100, 200, 300];
for (var i in ary) {
console.log(i);
}
JavaScriptでinは配列のeachではありません。
オブジェクトのプロパティ名をeachする命令です。
var obj = {key1: 100, key2: 200, key3: 300}
for (var key in obj) {
console.log(obj[key]);
}
var ary = [100, 200, 300];
for (var i = 0 ; i < ary.length ; i++) {
console.log(ary[i]);
}
functionという記述が長過ぎる
JavaScriptはシングルスレッドなので、callbackを多用します。
多用するのに毎回functionと書かなければいけません。
後からコードを見直すと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を書き忘れるとグローバルになるので他のライブラリと・・・
// グローバル汚染します
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
比較が曖昧
比較時に勝手に変換すると予期せぬ挙動となります。
なので毎回===と書かなくてはいけない。
"" == "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です。
それぞれ例をみていきましょう。
class Person
constructor: () ->
@name = "takashi"
@age = 20
echo: () ->
"Hello #{@name} !!"
class Employee extends Person
constructor: () ->
super
echo: () ->
"Hello #{super()}"
# 配列のループ
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)
$.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コンパイル時にbare=trueで関数で囲んでくれる
class Person
constructor: () ->
@name = "takashi" # インスタンス変数
@word = "Hello #{name} !!" # ローカル変数
}
new Person()
name # -> undefined
"" == "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を採用したことで以下の恩恵を受けることができます。
- ソースコードが簡素になったことで保守性があがります。
- JavaScriptの罠に嵌らなくなります。
あれ?少ない?
いえいえ、すごく大事な2点です。
塵積です。
でも待って・・・実は問題山積みなんです。
CoffeeScriptはコンパイルが必要です。
このコンパイルを甘く見てはいけません。
やってみればわかります。めんどいです。
私もCoffeeScriptコンパイルジプシーです。
・・・この投稿はとりあえずここまで!!
次回私が行ったCoffeeScriptのコンパイル方法の変遷を紹介します。
書きました。
私のCoffeeScriptをコンパイルする方法の変遷