jshitaの日記

勉強したことを書いていきます。

CoffeeScript 基礎

ドットインストールでCoffeeScript を勉強したので内容をメモ。

公式 http://coffeescript.org/

コメントの書き方

# 単体コメント

###
複数行の
コメント
###

JavaScript との構文の違い

  • var は省略可能
  • 文末の ; は省略可能
  • ブレース {} はインデントで表現する
  • () は可能であれば省略可能

例えば、以下の JavaScript コード

var say = true;
if (say) {
    console.log("Hello world");
}

これを CoffeeScript で書くと以下のようになる。

say = true
if say
    console.log "Hello World"

また、 <JSのコード> のように、` で囲めば直接 JavaScript を埋め込む事も可能

文字列

式展開

ダブルクォートで囲んだ文字列内に #{varname} と記述する場合、変数展開される

name = "takahashi"

# 出力:Hello takahashi
console.log "Hello #{name}"

複数行

文字列を複数行に記述してインデントした場合、インデントを自動的に除去した JavaScript に変換してくれる。

msg = "I
       am
       a
       japanese"

# 出力:I am a japanese
console.log msg

ヒアドキュメント

ダブルクォート3つで囲んだ文字列はヒアドキュメントとして解釈される。

html = """
       <div id="main">
         Hello World
       </div>
       """

# 出力:<div id=\"main\">\n  Hello World\n</div>
console.log html

配列の扱い

配列の要素をカンマ区切りではなく、改行にすることが可能。

a = [
    "taro"
    "joro"
    "saburo"
    "siro"
    "goro"
    ]

部分配列や部分文字列に範囲記法が使える。

# 配列の要素すべて
console.log a[..]

# a[3]〜最後の要素まで
console.log a[3..]

# 最初の要素〜a[3]まで
console.log a[..3]

# 部分文字列の取得も可能
console.log "japan"[1..3]

オブジェクトの記述

CoffeeScript の場合、オブジェクトの記述は yaml 形式でも可能。

例えば以下の JavaScript コードの場合

obj = {name: "taro", status: {age: 25, height: 172}}
console.log(obj)

CoffeeScript では以下の2種類の記述が可能

# CoffeeScript で書いた場合
obj = name: "taro", status: {age: 25, height: 172}
console.log(obj)

# CoffeeScript では yaml 形式の記述も可能
obj =
    name: "taro"
    status:
        age: 25
        height: 172

console.log(obj)

if 文

say = true

# 三項演算子 (say) ? ("foo") : ("bar") は使えないが、以下の記述が可能
if say then console.log "foo" else "bar"

# 後置記法が使える
console.log "foo" if say

条件分岐

CoffeeScript では、あいまいな比較は自動的に厳密な記述に変換される。

例. == -> === != -> !==

条件分岐の連結

例えば「 x が 10 ~ 20 の範囲に含まれるか」という記述は以下の表記法が可能

console.log "ok" if 10 < x < 20

条件分岐の記述方法

また、is, isnt や and, or のような条件分岐の記述も可能

=== -> is !== -> isnt

true -> yes on false -> no off

&& -> and || -> or ! -> not

要素の存在確認

in 要素を含むか判定

alert "ok" if 5 in [1, 3, 5]

of オブジェクトのキーを含むか判定

obj =
    name: "taro"
    age: 25
alert "exists" if "taro" of obj

switch 文

case ではなく when と記述し、コロンを記述しなくても良い。

JavaScript

var type = "red"

switch (type){
    case "red":
        console.log "赤"
        break;
    case "green":
        console.log "緑"
        break;
    case "blue":
        console.log "青"
        break;
    default:
        console.log "otherwise"

}

CoffeeScript

type = "red"

switch type
    when "red"
        console.log "赤"
    when "green"
        console.log "緑"
    when "blue"
        console.log "青"
    else
        console.log "otherwise"

# 以下のような記述も可能

switch type
    when "red" then console.log "赤"
    when "green" then console.log "緑"
    when "blue" then console.log "青"
    else console.log "otherwise"

繰り返し

for は以下の記述が可能

# for - in 構文
for i in [0..10]
  console.log i

# 後置 for 
console.log i for i in [0..10]

# 後置 for に

# インクリメントを2ずつ増加する for 
console.log i for i in [0..10] by 2

配列内包

for 文の結果を変数に代入する記法

values = (i for i in [0..10] by 2)
console.log values

while でも可能。

arr = while i < 10
    sum += i
    i++
console.log arr

オブジェクトの場合は以下の通り

obj =
    taro: 100
    jiro: 20
    saburo: 250

for name, score of obj
    console.log "#{name} = #{score}" 

# または console.log "#{name} = #{score}" for name, score of obj

関数

関数の書き方は以下の通り。

func = (name = "unknown") -> console.log "Hello #{name}"
func("taro")

また、即時関数という定義すると同時に実行する記述法も存在する

do -> console.log "foobar"

分割代入

値を複数変数に分割して代入する記法

[a, b, c] = [1, 10 ,100]
# 1 10 100 と表示
console.log a, b, c

# 変数値のスワップも1行で書ける
[a, b, c] = [c, b, a]

# 100 10 1 と表示
console.log a, b, c

オブジェクトの値を代入する場合はキーと同名の変数を渡せば良い

user =
    name: "taro"
    age: 25
    height: 172

# [ ] と違い、{ } で囲む点に注意
{name, height} = user

# taro 172 と表示される
console.log name, height

クラス

下記のような書き方ができる。 メンバ変数は先頭に @ と書く。

class User
  #
  # constructor: (@name, @email) -> 
  # というふうに1行で書くことも可能
  #
  constructor: (name, email) ->
    @name = name
    @email = email
  say: ()-> console.log "I am #{@name}"

taro = new User("taro", "taro@example.com");
# "I am taro" と表示される
taro.say()

継承の書き方は extends 句で行う。

class User
  constructor: (@name, @email) ->
  say: ()-> console.log "I am #{@name}"

class AdminUser extends User
  say: ()-> process.stdout.write "(Admin):"; super()

taro = new AdminUser("taro", "taro@example.com");
# "(Admin):I am taro" と表示される
taro.say()

存在演算子

CoffeeScriptでは ? という演算子で、変数や関数が定義されているかどうかを判定できる。

#
# 以下のコードの出力結果は
#
# found
# found
# not found
#   
# となる
#
for x in [0, false, undefined]
    if x? then console.log "found" else console.log "not found"

まとめ

全体的に RubyPython の構文に近いかたちで JavaScript が書けるから楽しい! あと後置 if とか for が地味に便利で楽しい。