Edited at

ES2015~2017に無い初見殺しコード3つ紹介

More than 1 year has passed since last update.

皆さんもう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つをご紹介しました。

これがわかれば、あとはなんとなくコード読めるかなーという気がします。