undefined

bokuweb.me

CoffeeScript基礎文法最速マスター


CoffeeScriptの文法について理解していないとこが多かったので、自分の覚書もふくめまとめてみました。

基本

  • CoffeeScriptはJavaSciprtにコンパイル可能な言語
  • CoffeeScriptはインデントでブロックを表現する
  • 行末の;(セミコロン)は不要
  • 数値表現、四則演算はjavascriptと同様

コンパイル

$ coffee -c hoge.coffee

例えば

hoge = "hogehoge"
console.log hoge

は以下のようなjavascriptにコンパイルされます

(function() {
  var hoge;
  hoge = "hogehoge";
  console.log(hoge);
}).call(this);

無名関数で括りたくない場合は

$ coffee -cb hoge.coffee

とします。

ログ出力

console.log "hoge"

出力

hoge

コメント

#でコメントアウトされます

#コメントです

複数行の場合は#3つで囲む

###
コメントです
hogehoge
fugafuga
###

変数

javascriptでは変数宣言の前にvarを置かないかぎりグローバル変数として宣言したことになる CoffeeScriptでは自動的に全ての変数宣言にvarがつけられる

CoffeeScript

hoge = "hoge"

javascript

var hoge;
hoge = "hoge";

文字列

hoge = "hoge"
fuga = 'fuga'

ダブルクォテーションの場合#{変数名}で変数が展開されます

fuga ="fuga"
hoge = "hoge#{fuga}"
console.log hoge

出力

hogefuga

シングルクォテーションの場合は展開されません

fuga ='fuga'
hoge = 'hoge#{fuga}'
console.log hoge

出力

hoge#{fuga}

文字列の操作

hoge = "hoge"
fuga = "fuga"
console.log hoge + fuga

出力

hogefuga

ヒアドキュメント

"""ダブルクォテーション3つで囲むと複数行の文字列を扱える #{変数名}で変数が展開される

name ="bokuweb"
text ="""
hogehoge
fugafuga
#{name}
"""
console.log text

出力

hogehoge
fugafuga
bokuweb

'''シングルクォテーション3つで囲むと変数は展開されない

name ="bokuweb"
text ='''
hogehoge
fugafuga
#{name}
'''
console.log text

出力

hogehoge
fugafuga
#{name}

エイリアス

@はthisのエイリアス

@hoge = "hoge" # this.hoge = "hoge"と同じ

::はprototypeのエイリアス

hoge::fuga = -> console.log "hoge" # hoge.prototype.fuga = と同じ

演算子

演算子のエイリアス

JavaScript CoffeeScript
=== is
!== isnt
! not
&& and
|| or
true true,yes,on
false false,no,off
of in
** Math.pow(a,b)
// Math.floor(a / b)
%% (a % b + b) % b

比較演算子の連結

こういった表現ができます。

if a > b > c then console.log "hoge"

存在演算子

存在演算子「?」を使うと、値がnullやundefined以外の時は true を返す javascriptより変数に値が入っているか簡単に調べられる

hoge = null
if hoge? # true
  console.log fuga

3項演算子

CoffeeScriptでは?は存在演算子に使用されているためif ~ then ~ elseで代用

a = if b then 1 else 2

if文

1行if

条件部との区切りにthenを使う

if hoge then console.log "hoge"

後置if

hoge = 5
console.log "hoge" if hoge is 5 # hogeと出力される

unless

unless false
  console.log "hoge" # hogeと出力される

swith文

CoffeeScriptではcase、defaultではなく、whenとelseで書きます。

switch val
  when 1
    console.log "1"
  when 2 then console.log "2"
  when 3,4,5
    console.log "3,4,5"
  else
    console.log "else"

配列

配列はインデントをカンマの代わりに区切に用いることができる。 ただし角括弧([])は必須。

array1 = [1, 2, 3]

array2 = [
  1
  2
  3
]

range

最初と最後の位置を示す2つの数値は..か...で区切られる。

array1 = [1..10]   # array1は1から10
array2 = [1...10]  # array2は1から9

もし範囲が変数の直後に置かれたならCoffeeScriptはそれをslice()メソッドの呼出に変換する 以下の場合元の配列の最初の2つの要素のみを持つ配列を返す

firstTwo = ["one", "two", "three"][0..1]

オブジェクト

object1 = {one: 1, two 2}

# 中括弧省略
object2 = one: 1, two: 2

# 改行をカンマの変わりにする
object3 =
  one: 1
  two: 2

for文

配列のループ

for i in [0..9]
  console.log i

###
出力
0
1
2
3
4
5
6
7
8
9
10
###

要素をスキップして繰り返す

for i in [0..10] by 2
  console.log i

###
出力
0
2
4
6
8
10
###

配列を逆からループ

array = [0, 2, 4, 9]
for v, i in array by -1
  console.log "i = " + i + " v = " + v

###
出力
i = 3 v = 9
i = 2 v = 4
i = 1 v = 2
i = 0 v = 0
array = [
  'one'
  'two'
  'three'
]
for i in [0...array.length]
  console.log array[i]

###
出力
one
two
three
###
array = [
  'one'
  'two'
  'three'
]
for value in array
  console.log value

###出力
one
two
three
###

繰り返しのインデックスがいる場合

array = [
  'one'
  'two'
  'three'
]
for value,i in array
  console.log "i=" + i + ",value = " + value

###
出力
i=0,value = one
i=1,value = two
i=2,value = three
###

forも1行でかける

for i in [0..9] then console.log i

もしくは

console.log i for i in [0..9]

これは

array = for i in [0...10] then i * i

このようにもかける

array = (i * i for i in [0...10])

フィルタリングもできる この場合値が3未満の要素を含む配列を返す

array = [0, 1, 2, 3, 4, 5]
array2 = for value in array when value < 3 then value
console.log array2

###
出力
[0, 1, 2]
###

オブジェクトのループ

オブジェクトの場合「in」ではなく「of」を使う

obj =
  'one'   : 1
  'two'   : 2
  'three' : 3
for key,value of obj
    console.log "key=" + key + ",value = " + value

出力
key=one,value = 1
key=two,value = 2
key=three,value = 3
###

while文

count = 0
while count < 15
  count++

console.log count  #15

後置whileも使える

count = 10
console.log "count = #{count}" while count--

###
出力
count = 9
count = 8
count = 7
count = 6
count = 5
count = 4
count = 3
count = 2
count = 1
count = 0
###

until文

count = 0
count++ until count >= 10
console.log count  #10

loop文

while trueと同じ

count = 0
loop
  if ++count >= 15 then break
console.log count  #15

関数

返り値を持った関数

返値は最後に処理した値になる。(関数の最後の行とは限らない。)

func = ->
  sum = 1 + 1

返り値なし

値を返したくない場合じゃ明示的にreturnを付ける

func = ->
  sum = 1 + 1
  return

引数を持つ場合

func = (arg1,arg2)->
  sum = arg1 + arg2

デフォルト引数

func = (arg1 = 1,arg2 = 5)->
  sum = arg1 + arg2

無名関数の即時実行

do->
  sum = 1 + 1

引数を持つ無名関数の即時実行

do(num)->
  num + 1

可変長引数

func = (x,args...)->
  console.log args

関数コンテキスト

以下のようにした場合、2行目の@すなわちthisはelementに等しくなる。 それにより以下のコードは期待した動作にならない。

@clickHandler = -> alert "clicked"
element.addEventListener "click", (e) -> @clickHandler(e)

CoffeeScriptでは->の代わりに=>(ファットアロー)を使用することでthisをローカルコンテキストにバインドできるようです。

@clickHandler = -> alert "clicked"
element.addEventListener "click", (e) => @clickHandler(e)

上記のものをコンパイルすると以下のようなjavascriptが生成されます。

(function() {
  var _this = this; // thisをバインド

  this.clickHandler = function() {
    return alert("clicked");
  };

  element.addEventListener("click", function(e) {
    return _this.clickHandler(e); // thisではなく_thisを使用
  });

}).call(this);

クラス

クラスの宣言

class Hoge

インスタンスの作成

クラスのインスタンスはnew演算子を用いて作成する

fuga = new Hoge

コンストラクタの定義

インスタンス化時にconstructorが実行されます

class Hoge
  fuga : "fuga"
  constructor: (name) ->
    @name = name

クラスの拡張

extendsキーワードでクラスの拡張が可能

class Fuga extends Hoge

super

スーパークラスの関数をsuper()で呼ぶことができる

class Hoge
  constructor: (name) ->
    @name = name

class Fuga extends Hoge
  constructor: ->
    super("Fuga")

private変数/関数

以下のようにすればよいらしい

class Hoge
        private1 = 1
        private2 = ->
                console.log "hoge"

別ファイルのクラスを参照

別ファイルのクラスを参照しようと思ってもCoffeeScriptのコンパイル時に無名関数でラッピングされてしまい別ファイルからクラスが見えなくなる。 例えば

class Hoge

はコンパイルすると以下のようになる

(function() {
  var Hoge;

  Hoge = (function() {
    function Hoge() {}

    return Hoge;

  })();

}).call(this);

これにより別ファイルからHogeは見えなくなる。

対策としてclass名に@をつければいいっぽい これによりクラス名がグローバルなスコープに追加される

class @Hoge

正規表現

javascriptと同様ですが、///で囲むことで複数行にわたってパターンを記述できる。

以下のページがわかりやすい javascript入門/正規表現編

OPERATOR = /// ^ (
  ?: [-=]>             # function
   | [-+*/%<>&|^!?=]=  # compound assign / compare
   | >>>=?             # zero-fill right shift
   | ([-+:])\1         # doubles
   | ([&|<>])\2=?      # logic / shift
   | \?\.              # soak access
   | \.{2,3}           # range or splat
) ///

コンパイル後

OPERATOR = /^(?:[-=]>|[-+*\/%<>&|^!?=]=|>>>=?|([-+:])\1|([&|<>])\2=?|\?\.|\.{2,3})/;

javascriptの挿入

バッククォーテーションでくくった部分はJavaScriptとして挿入される

`
var hoge;
console.log(hoge);
`

参考記事