ECMAScript Harmonyで提案されているDestructuring AssingmentがCoffeeScriptに実装されていて地味に便利なので紹介。harmony:destructuringを元にしているらしいけど、実際に実装されてるシンタックスを調査してみた。CoffeeScriptのバージョンは1.3.3。
配列の分解
[a, b] = [1, 2]
console.log a, b # 1 2
左辺に配列リテラルで変数を書き配列を代入すると、展開された配列の値が変数に代入される。
深い配列
[a, b, [c, d, [e]]] = [1, 2, [11, 12, [21]]]
console.log a, b, c, d, e # 1 2 11 12 21
深い配列でもさくっと変数に値を展開できる。
restオペレータ
[a, b..., c] = [1, 2, 3, 4, 5]
console.log a, b, c # 1 [2, 3, 4] 5
途中を配列に込めるなんてことも。
入れ替え
a = 1
b = 2
[a, b] = [b, a]
console.log a, b # 2 1
tmpなんていう変数が必要なくて便利。だけどJavaScriptにコンパイルすると・・・
var a, b, _ref;
a = 1;
b = 2;
_ref = [b, a], a = _ref[0], b = _ref[1];
console.log(a, b);
こんな感じに、配列を作って参照・代入するのでパフォーマンスが求められるケースでは注意して使用すべき。
スキップ
[a, , b] = [1, 2, 3]
console.log a, b # PARSE ERROR ON LINE 2: UNEXPECTED ','
harmony:destructuringでは提案されてるけど、CoffeeScriptでは不要な値を飛ばして取得することはできない。
オブジェクトの分解
{foo: a, bar: b, baz: c} = {foo: 1, bar: 2, baz: 3}
console.log a, b, c # 1 2 3
左辺にオブジェクトリテラルで変数を書きオブジェクトを代入すると、展開された配列の値が変数に代入される。
深いオブジェクト
{foo: a, bar: {barfoo: b}, baz: c} = {foo: 1, bar: {barfoo: 21}, baz: 3}
console.log a, b, c # 1 21 3
深いオブジェクトでもさくっと変数に値を展開できる。
ショートハンド
{foo, bar, baz} = {foo: 1, bar: 2, baz: 3}
console.log foo, bar, baz # 1 2 3
key-valueで分解しなくてもkeyで分解できる。
{foo, bar: {barfoo}, baz: c} = {foo: 1, bar: {barfoo: 21}, baz: 3}
console.log foo, barfoo, c # 1 21 3
柔軟にコンパイルしてくれるので混ぜて使うことも可能。
引数の分解
f = ([a, b, c])-> console.log a, b, c # 1 2 3
f [1, 2, 3]
f = ({foo: a, bar: b, baz: c})-> console.log a, b, c # 1 2 3
f {foo: 1, bar: 2, baz: 3}
f = ({foo, bar, baz})-> console.log foo, bar, baz # 1 2 3
f {foo: 1, bar: 2, baz: 3}
関数の引数でも使用できる。