旧それなりブログの跡地、画像やスタイルやJSなどが壊れてることがあります。

CoffeeScript 事始 その2

2013年6月9日

前回は、主に環境構築周りをまとめました。

今回は、個人的にハマったり記憶に残ってることを、つらつらと書いていこうと思います。

不一致判定には isnt

Python のノリで is not と書くと期待通りに動きません。

例えば、こんな結果になる

coffee> 0 is not 1
false

なぜならば、JSへ変換するとこうなるためです

0 === !1;

この場合は isnt (JSでは !== へ変換) を使います

coffee> 0 isnt 1
true

この辺の演算子の対応の話は、本家マニュアルの "Operators and Aliases" のセクションに
表でまとまっているので、軽く見ておくと良いです。

三項演算子は if then else

何も調べずにこれ書いたらコンパイルが通ったので

a ? 1 : 2

これでいいのかな?と思ってたら、全然違いました。

正しくはこう書きます

if a then 1 else 2

間違ってた方は、本当に全然違うので、興味が合ったら確認してください。
とりあえず、1 : 2 の部分は { 1 : 2 } という解釈になってます。

in と of

配列に対する値の存否判定には in を、
オブジェクトに対するキーの存否判定には of を使います。

coffee> 10 in [10]
true
coffee> 'x' of {x:1}
true

何はともあれ、JS での in が Coffee では of になっているのが間違え易い!

じゃあ、配列に対するキーの存否判定に of が使えるかというと..

coffee> 1 of [0,0]
true

.. 使える!

んじゃ、オブジェクトに対する値の存否判定に in が使えるかというと..

coffee> 1 in {x:1}
false

もちろんこれも使え..ない!? あれれっ!!?

JSへの変換結果を見ると、確かに使えないんだけど、なんでこうなんだろう?

ちなみに、of は 単純に JS の in にマッピングしているだけなので

coffee> 'push' of []
true

こうなるし..

coffee> 'hasOwnProperty' of {}
true

こうにもなる。hasOwnProperty は通してくれません。

これでコンパイルしちゃうと、JSLint には通らなくなると思うんだけど、
コンパイルオプションとかで回避する方法あるんでしょうか?
・・・ JSLint 自体が要らないってことでいいのか。

無名関数を代入するには ->

空の無名関数を代入する場合は、これが一番短い書き方です

func = ->

別に何てことはない書き方ですが、
個人的に、見た目が変だと感じるコードなので、特に書いてみました。

矢印の先..大丈夫かな? 刺さりそうで危なくないですか?

-> と => の違い

-> は、普通の無名関数の代入です。
=> も同じく無名関数を表しますが、内部の this を定義場所のスコープに静的に束縛します。
つまり、var self = this とか var that = this を書かないで良いってことです。

-> の場合:
Coffee

f = -> @

JavaScript

var f;

f = function() {
  return this;
};

=> の場合:
Coffee

f = => @

JavaScript

var f,
  _this = this;

f = function() {
  return _this;
};

イチイチ、自前でクロージャにしなくていいので楽だし、
特に class の記法と合わせると、適切に => を使えば、
「クラスインスタンスが @ 」という最も期待する動作を簡潔に書けるので、とても良いです。

なお蛇足ですが、-> は アロー (or シングルアロー) という名前で、
=> は ファットアロー というらしいです。
・・・ぼくは、心の中で 烈風拳 と ダブル烈風拳 って呼んでました。

文字列への変数埋め込み

"#{変数名}" で埋め込めます

coffee> age = 35; "I am #{age} years old."
'I am 35 years old.'

文字列の定義をシングルクォートで行った場合は、これは無効になります

ヒア・ドキュメント

以下の Coffee の例は、両方共に ‘aaa\niii\nuuu’ という文字列を定義しています。

text = "aaa\n
iii\n
uuu"

text = """aaa
        iii
        uuu"""

改行含めて文字列を定義できるってだけで、JavaScript的にはうれしいのに、
更に """ の方は、行頭のインデントをデフォルトで無視してくれるのが良い!

prototype は :: を使う

例えば、Array.prototype は Array:: と書きます

coffee> func = -> Array::slice.call(arguments, 1, 2)
[Function]
coffee> func(11, 22, 33)
[ 22 ]

.. と、良く有るケースで使ってみました。

ただ、Coffee としては、prototype 自体をあんまり意識させたくなさそうなので、
そもそも使わないようにした方がいいのかもしれません。

以上

次回はクラス周りをまとめようと思います