JS リーディング@20120217
今日は社内で毎週開かれている JS リーディングに参加しました。今日の参加者は僕も含めて4人。
今日は The Little Book on CoffeeScript をみんなで読んでみようということになりました。
まぁ本当はこれくらいは一人で週末とかでさくっと読めよ、という話なんですが、わいわい言いながら読むのはまた違う趣があります。
今日は 2.文法 のフローコントロールの最後まで読みました。
該当の箇所を読めば全部分かるので、書くほどでもないですが、気になったところをいくつか。
- コメント
- 一行のコメントは生成された JS には残らない。複数行のコメントは残る
- Coffee は空白 (インデント) に意味を持つ (Python のように)
- 変数とスコープ
- JavaScript GoodParts で推奨されていたような、全て var 宣言された変数が生成された一番上に列挙される
- グローバル変数は基本的には作られない
- グローバル変数を使いたい場合は Window オブジェクトのプロパティとして代入するか、以下のようなイディオムで使う
exports = this exports.MyVariable = "foo-bar"
- 関数
- -> が function
func = -> "bar" // は以下のようになる var func; func = function() { return "bar"; };
-> "bar" // で無名関数 (function() { return "bar"; });
- 関数引数
times = (a, b) -> a * b times = (a = 1, b = 2) -> a * b // デフォルト引数が持てる。通常の JS ではできない。 # でも生成される JS は泥臭いですね^^ var times; times = function(a, b) { if (a == null) { a = 1; } if (b == null) { b = 2; } return a * b; };
-
- 可変長引数は ... (スプラットと読むらしい、知らなかった) で表現できる
sum = (nums...) -> result = 0 nums.forEach (n) -> result += n result
-
- これは以下のように生成される
var sum; var __slice = Array.prototype.slice; sum = function() { var nums, result; nums = 1 <= arguments.length ? __slice.call(arguments, 0) : []; result = 0; nums.forEach(function(n) { return result += n; }); return result; };
- __slice (__*) は coffee の予約語になり宣言できない
- Array.prototype.slice を なぜ __slice に一度いれなければいけないかは分からなかった
- __ でメソッドを定義して、生成する感じ、utility 関数的に宣言を行って可読性をあげるため?
- nums = 1 <= arguments.length ? __slice.call(arguments, 0) : []; で arguments オブジェクトではなく、本物の配列として扱う
- Array.prototype.slice は 404 Blog Not Found:javascript - Array.prototype.slice.apply(arguments) // 引数一発配列化 に詳しい
- Array.prototype.slice を なぜ __slice に一度いれなければいけないかは分からなかった
- 関数の実行
- 以下3つはすべて同じ。最低でも一番下の例のような inspect の実行には括弧を付けることを推奨
alert inspect a alert(inspect(a)) alert inspect(a)
- 関数コンテキスト
this.clickHandler = -> alert "clicked" element.addEventListener "click", (e) => this.clickHandler(e) // 上の例は以下のように出力されるとあるが var __bind = function(fn, me){ return function(){ return fn.apply(me, arguments); }; }; this.clickHandler = function() { return alert("clicked"); }; element.addEventListener("click", __bind(function(e) { return this.clickHandler(e); }, this)); // http://coffeescript.org/ で試すと、出力される結果が異なる __bind を出さなくなった? var _this = this; this.clickHandler = function() { return alert("clicked"); }; element.addEventListener("click", function(e) { return _this.clickHandler(e); });
- CoffeeScriptを使うべきか、使わざるべきか? - にのせき日記 でもファットアロウについて言及があるが、もし jQuery を使っているなら $.proxy を普通に使うことも可能
- オブジェクトの構文と配列の定義
- 中括弧なしで書ける。User.create(name: "John Smith") これはいい。
- 配列はインデントをカンマの区切りとして使える。Ruby の %w のような。
- フローコントロール
a = if foo then "bar" else "baz" # が以下のようになる var a; a = foo ? "bar" : "baz"; a = foo ? "bar" : "baz" // 三項演算子を上のように coffee で書くとは以下のように出力される a = typeof foo !== "undefined" && foo !== null ? foo : { "bar": "baz" };