deepblue-will’s diary

JS、CSS,Ruby、Railsなど仕事や趣味で試した技術系のことを書いていきます。

CoffeeScript書くなら知っておくと便利な記法

今、CoffeeScriptでお仕事してて、JavaScriptにない便利な書き方を色々知ったので書き出してみました。
この中のいくつかはES6で対応されるみたいだけど。

それ実は1行で書けるよ編

if, unless

if, unlessの中が1行だけならまとめて1行で書けます。

coffee

hoge = true
console.log "hoge" if hoge

js

var hoge;
hoge = true;

if (hoge) {
  console.log("hoge");
}

for

for文にwhenを使うことで条件を指定できる

coffee

ary = [1..10]

# これは
for i in ary
  if i % 2 == 0
    console.log i

# こう書くことができます
for i in ary when i % 2 == 0
  console.log i

js

var ary, i, j, k, len, len1;

ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];

for (j = 0, len = ary.length; j < len; j++) {
  i = ary[j];
  if (i % 2 === 0) {
    console.log(i);
  }
}

// 同じコード
for (k = 0, len1 = ary.length; k < len1; k++) {
  i = ary[k];
  if (i % 2 === 0) {
    console.log(i);
  }
}

filter, mapいらず

Array.prototype.filter()Array.prototype.map()を使わずに1行で同じようなことができます。
ie8もサポートしないといけない人にとっては嬉しい。

coffee

ary = [1..10]

# 先に配列を用意しておく方法
result = []
result.push i for i in ary when i % 2 == 0

# ↑はさらに1行にできる
result2 = (i for i in ary when i % 2 == 0)

js

var ary, i, j, len, result, result2;
ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
result = [];

for (j = 0, len = ary.length; j < len; j++) {
  i = ary[j];
  if (i % 2 === 0) {
    result.push(i);
  }
}

result2 = (function() {
  var k, len1, results;
  results = [];
  for (k = 0, len1 = ary.length; k < len1; k++) {
    i = ary[k];
    if (i % 2 === 0) {
      results.push(i);
    }
  }
  return results;
})();

Object、Array

CoffeeSctiptの便利記法教えてもらったで知った記法。 ObjectやArrayの中身を1行で変数に代入するやり方。

coffee

hoge = {id: 1, name: "hoge"}

# id = 1, name = "name"
{id, name} = hoge

ary = [1..9]

# a = 1, b = 2, c = 3
[a, b, c] = ary

js

var a, ary, b, c, hoge, id, name;

hoge = {
  id: 1,
  name: "hoge"
};
id = hoge.id, name = hoge.name;

ary = [1, 2, 3, 4, 5, 6, 7, 8, 9];
a = ary[0], b = ary[1], c = ary[2];

function周りで知っておくと良いこと

-> と => の違い

CoffeeScriptではfunctionと書かずに->=>でfunctionを定義できます。
この時使用する矢印によってthisの扱いが変わります。
前者だとthisはfunctionの中を指しますが、後者だとthisはfuctionの外側のthisになります。

coffee

fnc = () ->
 console.log @

fnc = () =>
 console.log @

js

var fnc;

fnc = function() {
  return console.log(this);
};

fnc = (function(_this) {
  return function() {
    return console.log(_this);
  };
})(this);

デフォルト引数

もし引数に何も渡さなかったり、nullundefinedが渡された時のデフォルト値を定義できます。

coffee

fnc = (arg = 1) ->
 console.log arg

js

var fnc;

fnc = function(arg) {
  if (arg == null) {
    arg = 1;
  }
  return console.log(arg);
};

可変長引数

引数の長さが固定でない関数を簡単に定義できます。 いわゆる可変長引数ってやつです。

coffee

func = (a, b...) ->
  console.log a
  console.log b

js

var func,
  slice = [].slice;

func = function() {
  var a, b;
  a = arguments[0], b = 2 <= arguments.length ? slice.call(arguments, 1) : [];
  console.log(a);
  return console.log(b);
};

その他便利な書き方

? でundefinedやnullのチェック

?をつかうことでundefinednullのチェックができます。
またそのまま.でつなぐと、チェック+プロパティの取得が一度にできます。

通常、undefinedのものに対してアクセスしようとするとTypeErrorで怒られるので、プロパティのアクセス時にチェックが必要なのですが、この書き方だとそれをしなくて済むので楽に書くことができます。

さらに、?=と書くと、undefinednull時のみ変数に代入することができます。
ただし、事前に変数定義がされている必要があります。

coffee

result = hoge? # false
result2 = hoge?.fuga # undefined
hoge = null
hoge ?= "hoge"

js

var result, result2;

result = typeof hoge !== "undefined" && hoge !== null;
result2 = typeof hoge !== "undefined" && hoge !== null ? hoge.fuga : void 0;

hoge = null;
if (hoge == null) {
  hoge = "hoge";
}

文字列中で変数の展開

文字列中に#{変数名}で変数を展開してくれます。
+で文字列を連結していく必要ななくなります。

coffee

hello = "Hello"
result = "#{hello} World!"

js

var hello, result;

hello = "Hello";
result = hello + " World!";

::でprototypeにアクセスできる

hoge.prototype.fugahoge::fugaと書くことができます。

coffee

hoge::fuga = () ->
 "fuga"

js

hoge.prototype.fuga = function() {
  return "fuga";
};

0以上100未満といった範囲の条件文が簡単に書ける

上記の場合hoge >= 0 && hoge< 100と書くところですが、0 <= hoge < 100と書くことができます。
直感的ですね。

coffee

i = 98
result = 0 <= i < 100

js

var i, result;
i = 98;

result = (0 <= i && i < 100);

Objectのキーを省略

変数名をそのままObjectのキーにする場合は定義するときにキーを省略できます。

coffee

id = 1
name = "hoge"

console.log {id, name, ex: "aaa"}

js

var id, name;
id = 1;
name = "hoge";

console.log({
  id: id,
  name: name,
  ex: "aaa"
});