CoffeeScriptこの記事が対応するCoffeeScriptのバージョンは1.7です。基本的には本家サイトCoffeeScriptの内容と同じです。わかりやすいように色々と私が勝手に再構築、追加してはありますが。)なお、JavaScriptの基礎知識を前提とし、JavaScriptから引き継ぎ重複する内容は解説されません。後、この記事の文章、CoffeeScriptコード、JavaScriptコードに関する著作権は放棄しています。パブリックドメインと言うそうです。文章、コード自由に引用改変公開しても問題ありません。演算子などはじめに:CoffeeScriptのメリットとデメリット一般に言われているCoffeeScriptを使うメリットデメリットを載せておきます。ま、こんな論争気にせず、使ってみて気に入ったら使い続ければいいし、気に入らなかったらやめればいいだけだと私は思うんだけどね。強調定義ファイル誰かがすばらしい定義ファイルを作ってくれる日を願って.........Theテキトーな自作定義ファイル。解析定義ファイルこれらのファイルをnodamushiの許可無く改変、再配布することを禁じません。そのような事態が発覚した場合、配布人へ謝意を申し上げに参ります。.........ま、そんな希有な人はいないだろうけど。coffee-script」と入力4.coffeeとタイプして動作を確認。(動かない場合はPATHの確認)Macなどでも1と3の手順で良いはず。"Hello"上記の内容をtest.coffeeとして適当なフォルダに保存。test.coffeeとタイプ。test.jsが同じディレクトリに作成されます。coffeeコマンドのオプション-cはjsファイルとしてコンパイル結果を出力するという意味。-bは全体を関数として囲わないようにします。同じファイル名+jsという名前ではなく、別なディレクトリに別な名前で保存したかったら-oオプションを指定する。JavaScriptファイルとして結果を出力する。ファイル名は元のcoffeescriptファイルと同名。以下の例はsrcフォルダ内にあるcoffeeファイルをコンパイルする。JavaScriptファイルの出力ディレクトリの指定。cオプションやwatchとあわせて使う。以下の例はsrcフォルダ内にあるファイルをまとめてlibフォルダに出力する。コンパイル前に、全てのスクリプトを渡された順番に結合する。大きなプロジェクトに使うと便利だそうです。バージョン1.1.0から結合後のファイル名を指定できるようになりました。出力結果を標準出力にプリントする。Lintがインストールされている場合、コンパイル結果をjslを使ってチェックする。wオプションと伏せて使うといいらしい。標準入力からcoffeeスクリプトを受け取り、標準出力へコンパイル結果を出力する。スクリプトをコンパイルまたは実行する前にライブラリーを読み込む。セーフティ関数で囲わない。簡単に言えば、大域環境に登録するようになる。CoffeeScriptをパースする代わりに、Lexで字句解析し、トークンストリームを出力。CoffeeScriptをパースする代わりに、Lexで字句解析し、構文木を出力。何か--debugや--max-stack-sizeとかのフラグでNodejsと連携できるらしいよ。誰か詳細求むコメント単一行#以降の文字がコメントとして扱われます#〜〜〜複数行###で囲った部分がコメントになります。ファイル先頭に書いた複数行コメントはそのままコンパイルファイルに出力されます。###〜〜〜###インデントpythonライクな言語なので、インデントの深さでブロックが生成されます。処理群1処理群2処理群3処理群4こんな感じのインデントになっていたらJavaScriptでは処理群1{処理群2{処理群3}処理群4}このような関係になる、という大雑把なイメージを持っておいてください。変数CoffeeScriptには変数宣言はありません。変数名=.........の様に初めて記述したところから変数が宣言された物と見なされます。@修飾子CoffeeScriptでは変数名の前に@を付けた場合、現在のオブジェクトが保有する変数を指すようになります。(だいたいthis.がついたのと同じ扱いになります。)@param=1↓this.param=1ただし、後述する関数バインドなどでは、@が単純にthisに変換されない場合もあります。一応、thisキーワードを使うことも可能ですが、@を使っておきましょう。関数チェーンなどで自分を返したいときに、@単体で使うこともできます。数値JavaScriptでは数値の書き方として10進数(例:11)8進数(例:013)16進数(例:0xb)があります。CoffeeScriptではv1.1.3からこれらに加え2進数表記が可能になりました。0b〜の形で表記します。以下の例は全て変数に11を代入しています。ダブルクォーテーション"とシングルクォーテーション'のどちらかで囲います。文字列は、下記例の様に複数行にわたって文を書けます。改行は文字列に適応されませんが、バージョン1.7から半角空白が挿入されるようになりました。行頭行末の空白は無視されます。無視されるンゴ';シングルとダブルの違いは式展開において違いが出ます。ヒアドキュメント'''〜〜〜'''とするとヒアドキュメントになります。Interpolation)ダブルクォーテーション内部では以下の様に書くと式の展開が行われます。#{式}シングルクォーテーションでは式は展開されません。式には変数名や、1+2などの数式を入れられます。'cat=#{cat}\nsogeb=#{sogeb}'コンパイル結果。配列作成CoffeeScriptでの配列宣言はJavaScriptと同様に宣言することが出来ます。改行も区切り文字として認識されます。23]範囲CoffeeScriptでは範囲を指定する構文があります。..a..bはa以上b以下、もしくはa以下b以上を表します。...a...bはa以上b未満、もしくはa以下bより大を表します。範囲の指定によりaからb未満(もしくはbより大)の連続する値を持つ配列を簡単に生成できます。[a...b]「..」と2点の場合はaからb以下(もしくはb以上)の連続する値を持つ配列になります。for文を利用した配列生成for文(後述)を利用すると[1,3,5,7.........101]といった配列も容易に生成できます。_results;})();配列要素へのアクセスJavaScript同様です。配列の範囲内の要素を取り出す配列ARRの添え字がaからbまでの要素を持つ配列arrなどを簡単に作成できます。9e9);arr=ARR.slice(a,b);arr=ARR.slice(a);arr=ARR.slice(0);配列の範囲内の要素を置換する[a..b]の記法は取り出す以外にもその範囲の要素に値を代入することも出来ます。#要素4が10に、要素5が11になる分割代入Perlを知っている方なら関数の引数を受け取るときに($a,$b,$c)=@_という風に、左辺の配列に入れた変数に右辺の配列の値を順に書き込めることをご存じかと思います。CoffeeScriptでも同じ事が出来ます。_ref[2];また、左辺の配列に入れる変数の一つだけ「...」を後ろにくっつけることが出来ます。これを付けた変数は適切な長さを持つ配列が代入されます。5]また、上のコンパイル結果を見ても分かるようにいったん_refという名前の変数に配列を入れてからa,b,cに値をコピーしているので、以下のような二つの値の交換も安全に実行できます。_ref[1];オブジェクト(連想配列)JavaScriptとほぼ同様です。「,」を記入せずにインデントを利用して作成することも出来ます。配列の時のような分割代入が行えます。連想配列のキーと同じ名前の変数に同じ名前のキーの値を代入することができます。「キー名:変数名」を指定すると、そのキーに対応する要素が変数名に格納されます。配列の時同様に深いネスト関係にあっても取得可能です。#phoneのオブジェクト内にあるtellを取得。id:mooz様:間違いの指摘ありがとうございました。bversion1.7から「**」、「//」、「%%」が追加されました。順に、累乗を計算する演算子、割り算の商を整数で返す演算子、あまりを正の数で返す演算子です。あまりを正の数で返すというのは「-3%5=-3」に対して「-3%%5=2」となります。JavaScriptの比較演算子「==」に対応する演算子は無いようです。比較演算子の連結pythonからの輸入で比較演算子を以下のように連結することが出来ます。(b)」という処理と同じ事になりますが、or=,||=,and=,&&=といった比較演算子の場合以下のように展開されます。bの値が入るのではなくaにはbが入るので注意してください。?条件式の??という演算子は存在しているか(nullやundefinedでないか)を返す演算子です。#変数aが存在しているなら続く処理を行うという意味になるこれだけだと単にnullやundefinedの時falseでそれ以外ならtrueを返すように聞こえますが、そのほかの機能も有したマルチな演算子です。二項演算子としての?a?b二項演算子として?を使うと上の式は次のような意味になります。1#aが無ければaに1を代入する。?.アクセス演算子?.演算子はセーフなアクセス演算子です。JavaScriptは実行してみないと、アクセスする要素が存在しているかどうか分かりません。それが問題となるとき?.アクセス演算子が役に立ちます。a?.bはaが存在するならばaのbにアクセスする、という意味になります。udefinedの要素にアクセスするエラーが発生しません。?.の形には.の代わりに関数の引数である()を入れた?()という形もあります。0;条件分岐if,unless,elseifは渡された条件式が真の時該当する処理を実行する。unlessは渡された条件式が偽の時該当する処理を実行する。elseはifもしくはunlessが成立しなかったときに実行される。if文、unless文は条件式との区別がつかないので、条件式の後に実行したい処理を記述することは出来ない。else文に関しては同じ行に実行する処理を書いても良い。上の例のように処理が一行しかないときはわざわざ改行して、インデントを下げて記述なんて面倒くさいですね。簡単に書く方法があります。処理と分岐条件の間にthenを入れるifを後ろに書く。(※else文の追加は出来ない。2JavaScriptで一般的な?を使った三項演算子は、?を存在演算子にしてしまった為使えません。switch文CoffeeScriptにおけるswitchでの分岐はcase、defaultではなく、whenとelseで書きます。when節で処理が一行のみで多段組にしたくないときはthenを使って一行にまとめられます。1,2と,区切りで書き並べます。#いくつかをまとめたいときは,区切り.........else.........ループwhile,untilCoffeeScriptでは単純なループはwhileを使います。条件式という簡略形の構文が使えます。whileではJavaScript同様にbreakやcontinue文などの制御構文が使えます。not(条件式)と同じ意味になるuntilというループ構文もあります。個人的な感想だけど、untilとかunlessはPerlで結局全然使わなかったなぁ.........whileは配列を返すwhileループはある種一つの関数の様なものとして扱われ、その返値は配列になります。->は無引数の関数を定義するという意味です。)一見何もしない関数を定義したようですが、これをコンパイルするとこうなります。_results;};このように_resultsという配列を返しています。whileで代入される配列の要素は処理の一番最後の結果になります。このためwhile文で終わる関数は必ず配列を返すようになります。while文で終わるが、本当は何も返さない関数の最後には明示的にnullを書かなければなりませんただし以下のような場合は、配列を返す理由がない(受取手がいない)ので配列を返しません。for配列内包とはCoffeeScriptにおけるfor文は配列内包という、配列の要素を順に取り出していって各要素について何らかの操作をし、新たな配列に格納するという、配列と連想配列操作の構文になっています。map関数と言ったら理解が早いかもしれません。while同様コンパイラが新たな配列に格納する必要がないと判断できる場合(返ってくる配列の受け取り手が以内場合)は新たな配列を作成しません。for文の構文for文は配列と連想配列に対して使うことが出来ます。新たな配列に格納する値は一回の処理で一番最後に行われる処理の返値や変数になります。処理が一行だけの時は以下のように簡略化して書くことも出来る。処理なお、要素を代入する変数は省略することが出来ます。処理が一行だけの時は以下のように簡略化して書くことも出来る。連想配列tips:インデックス変数は各ループ毎にイミュータブルバージョンが1.3.1からはインデックスの変数を変更してもループに影響が出ません。私の語学力では言葉で説明しにくいので、以下のソースコードを見て貰った方が早いでしょう。i=i*iループの処理の中でiの値を書き換えています。これをコンパイルすると以下の様になります。i;}この様に実際にループの終了判定は変数_iを用いているので、iの値を処理中に書き換えても、各ループ開始時のiの値は順に0から9まで増えていきます。tips:配列にアクセスするための値を格納する変数を決めるfor文で配列の要素にアクセスするためのキー(数値)を格納する変数は_iなどコンパイラ側が用意してくれますが、以下の様にして自分で定義することが可能です。arrこの様に、配列の要素を代入する変数の次にもう一つ変数を宣言すると、arrにアクセスするための変数がnumberになります。arr[number];といった感じになります。これを利用すれば、今何度目のループか?なども取得できるでしょう。break文,continue文javascriptのforループ同様にbreak文とcontinue文が使用できます。byfor文は配列の要素を順に取り出していくが、飛び飛びに取り出していくこともできる。次の要素までの距離デフォルトではbyの次の要素までの距離が1である。例:#数列1,3,5,7,9の総和の数列を作成する。返値は最後に処理した値になる。*1(関数の最後の行とは限らない。)明示的にreturnで関数から抜けることも出来る。引数がない場合は括弧は省略できる。関数で受け取る変数は初期値を設定することが出来る(x=0,y=1)->.........x,yが渡されなかった場合x=0,y=1が代入される。可変長引数...を変数名の後に加えることで、可変長引数となり、それ以降の引数を配列として受け取れる。引数,引数.........が、関数に引数が無いときには括弧が必要である。引数などの様に書くと関数名(引数+関数名(引数))の様に扱われてしまうので、括弧を付ける。関数名と括弧の間にスペースを入れてはいけない。3));tips:変数名の衝突スコープはRubyと同じらしい。(私実はRuby使えないけど。tempと変数宣言されています。この関数よりも前にグローバル領域に変数tempが宣言されている場合、コンパイラはグローバル変数tempと関数内部のtempを同じ物と見なしてしまい、ローカル変数宣言は行われません。ローカル変数かどうかをCoffeeScriptだけで指定する方法はないらしい*2ので名前の衝突が起こらないようにしなければならない。関数をjs風に書いてバッククォーテーションで囲むとそのまま出力されるので、どうしてもローカル変数を宣言したいならこれを使うしかない模様。バージョンが1.3.1以降ならば、do関数を利用することも考えられると思います。(関数にダミー引数を入れて、それをローカル変数として利用する方法も考えられます。可変長因数が使えなくなりますし、ソースコードの可読性が下がってしまうので、止めた方が良いと思います)do関数JavaScriptではループの中で、変数を保護するためにクロージャーを使うことが一般的なんだそうです。「do」というキーワードを用いて関数を定義すると、定義をしただけで自動的に実行をしてくれます。_fn(i);}この様に自動的に作成した関数を呼び出してくれています。バージョン1.3.1からdo関数のネームスペースが柔軟になりました。次のCoffeeScriptを考えます。このdo関数はxの初期値としてobj要素が"obj"というオブジェクトを与えています。alert(x.obj);})(x);この様になります。xはnullでないので、実行すると「1」がアラートされます。次に1.3.1以降でコンパイルするとこの様になります。"obj"});この場合、実行すると"obj"がアラートされます。外側のxと内側のxは別物だと言うことをよりはっきりさせたと言うことなのでしょう。関数バインディングaddEventListenerやjQueryのbindなどでイベントに関数を渡すとき、イベントに関数を渡した場所のオブジェクトの持つ変数vにアクセスしたくてうっかりthis.vなんてやって失敗しまくってないだろうか。(私だけ?)CoffeeScriptではその煩わしさを解消してくれるすばらしい関数定義の方法がある。()=>処理という構文だ。通常の関数定義が「->」に対して関数バインディングでは「=>」となっただけである。この構文内ではthisや@修飾子が指すオブジェクトが関数を定義したオブジェクトになる。@parametaalert(doc.innerHTML),false上の例では@parametaや@addは同じ物を指している。コンパイルするとこのようになる。false);};addEventListenerに渡している無名関数内の@adや@parametaがthisではなく、_thisに変更されていることがわかる。クラスJavaScriptのクラスは使いにくい。(というか、実際はクラスないけど...)super関数を呼び出すとか結構しんどいよね。CoffeeScriptにはそんな問題を一気に解決してくれるすばらしいクラス構文があります。.........member2:.........オブジェクト(連想配列)の構文にクラス宣言がついただけですね。以下の様にも追加できます。.........prototypeメンバへのアクセス以下の様にアクセスできます。.........クラス名::member()インスタンス内からはJavaScriptでやるように、thisを使ってアクセスすると良いです。thisの代わりに@修飾子を使うとタイプが楽です。new演算子クラスのインスタンスを生成するにはJavaScript同様にnew演算子を使います。コンストラクタークラスのインスタンスを生成する際に実行される関数、コンストラクターは以下の様に定義します。クラス名constructor:(引数)->処理クラス名::constructorで宣言してはいけません。後から追加するとコンストラクターが呼ばれません。クラスの拡張extendsキーワードを使うことでクラスを拡張することが出来ます。」でインスタンスがクラスのインスタンスかどうかを調べられます。このクラス名は拡張したクラス名でもきちんとtrueが返ってきます。#truesuperスーパークラスと同じ名前関数を定義することをオーバーライドといいます。オーバーライドした関数からスーパークラスの関数をsuperで呼ぶことが出来ます。oldとアラートtips:スーパークラスがオーバーライドされた関数を呼ぶときは?C++風に言うならば、CoffeeScriptのクラスの関数には全てにvirturalがついているような物です。以下の様に定義されているとき、Testクラスの関数aはTest2クラスのインスタンスから呼ばれたとき、Test2クラスでオーバーライドした関数bを呼び出します。́・∀・`)がアラートされます。tips:クラスの変数、関数prototypeメンバではなくクラスに属する変数や関数を定義するには以下の様にする。Test;})();tips:クラスの関数のオーバーライドについてv1.1.3からクラスに属する関数をオーバーライドしたときにsuperで呼び出すことが可能になりました。T)が入るようになり、呼び出せるようになっています。以前のバージョンだとconstructorが入りません。static〜みたいなのは以下の様に定義すればいいようだ。va:->privatefunc(privatevalue)#@やらthisはいらない。Test;})();JavaScriptの挿入バッククォーテーションでくくった部分はJavaScriptとして認識され、そのままjsファイルに書き込まれます。正規表現はJavaScriptの正規表現と変わりません。正規表現の使い方は下記のサイト等を参考にしてください。正規表現(RegExp)/パターン/オプション複数行///で囲むことで複数行にわたってパターンを記述できます。改行や空白は無視されます。例外処理JavaScriptと同様です。error処理finally処理throwも式1.2.0からthrowそれ自身も式として扱われるようになりました。具体的にはa=throw("throw")こんなソースコードが通るようになりました。コンパイルすると以下の様になります。"throw";})();.........で、これどこで使うんすか?CakefileCoffeeScriptにはMakefileの様な機能を持った物を作る事が出来ます。下記の記事で解説を書きました。function.だそうです。05:25関連記事2019-06-03組み込み屋こそC++を使うべきなのですやーやーやー。v1.7はーい、修論で死にそーなnodamushi様ですよ。»プロフィールJavaで画像AI屋だったハズが、気がついたら制御論理やってて、Eclipse開発してて、組み込み屋で、CortexM4周りの開発してて、VerilogでRTL書いてて、STAしてて、色んな小さいインフラ管理してる、何でも屋。働きたくないでござる。(14)スターをつけました引用をストックしましたストック一覧を見る閉じる引用するにはまずログインしてくださいログイン閉じる引用をストックできませんでした。再度お試しください閉じる限定公開記事のため引用できません。