皆さんもうES2015は大丈夫でしょうか?(私はいまだに理解が怪しいものがあります)
今回はES2015にもES2016にもES2017にもまだない、
だけどよく見る構文を3つ紹介したいと思います。
Rest/Spread Properties (stage-3)
spread operatorのオブジェクト版(初見殺しと言いつつ、1つめは大したことなかった)。
配列や関数の引数に対する(...)はES2015で追加されたんですが、
オブジェクトに対する(...)はまだ正式な仕様になっていません。
(...)をオブジェクトに対して使うと、以下のようなコードが書けるようになります。
// Rest Properties
let { x, y, ...z } = { x: 1, y: 2, a: 3, b: 4 };
x; // 1
y; // 2
z; // { a: 3, b: 4 }
// Spread Properties
let n = { x, y, ...z };
n; // { x: 1, y: 2, a: 3, b: 4 }
Rest Propertiesは残りのプロパティを変数に入れる構文です。
逆にSpread Propertiesの方は中身のプロパティを展開するような振る舞いをします。
Spread Propertiesの方はオブジェクトをコピーするのによく使いますね。
Class and Property Decorators (stage-2)
@関数 の形式で記述するデコレータもよく見るんですが、
これは知らずに見ると初見殺しなコードじゃないでしょうか。
例えば次のようなコードは...
@bar
class Foo{
}
やってることは以下と同じです(説明が雑ですね)
class Foo{
}
bar(Foo);
やってることはシンプルで、直後のクラスに対して装飾しているだけです。
分かるとコードの見通しが良くなって良いですね。
ちなみに複数つけると...
@bar;
@baz;
class Foo{
}
以下のようにbaz -> barの順に評価されます。
class Foo{
}
bar(baz(Foo));
Function Bind Syntax (stage-0)
bind operator (::) も知らずに出くわすと「なにこれ!?」となると思います(私はなりました)。
用途はbindやcall関数などでthis参照を縛るときの糖衣構文になります。
これはまだstage-0(アイデア段階)なんですが、便利なので既に結構使われています。
例えば次のような変数を定義したとして...
var foo = {
baz: function(){
console.log(this);
}
}
var bar = function(){
console.log(this);
}
以下のような感じで使います。
// オブジェクト::関数 の形式
foo::bar;
foo::bar();
// ::オブジェクト.メソッド の形式
::foo.baz;
::foo.baz();
上記はそれぞれ次のコードと同じ意味合いになります。
// オブジェクト::関数 の形式
bar.bind(foo);
bar.call(foo);
// ::オブジェクト.メソッド の形式
foo.baz.bind(foo);
foo.baz.call(foo);
特に ::オブジェクト.メソッド の方はclass内でthis参照を縛るのによく使ってるのを見ますね。
this参照を縛らない場合、以下のコードでbaz関数ではwindowが表示されますが...
class Foo {
baz(){
console.log(this); // window
}
bar(){
setTimeout(this.baz, 100);
}
}
new Foo().bar();
:: をつけるだけで簡単にthisを自分にすることができます。
class Foo {
baz(){
console.log(this); // Foo
}
bar(){
setTimeout(::this.baz, 100); // ::this.baz は this.baz.bind(this) の意味
}
}
new Foo().bar();
以上、よく見るけどまだあまり解説を見ない構文3つをご紹介しました。
これがわかれば、あとはなんとなくコード読めるかなーという気がします。