54
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

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

Last updated at Posted at 2017-01-23

皆さんもう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つをご紹介しました。
これがわかれば、あとはなんとなくコード読めるかなーという気がします。

54
43
7

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
54
43

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?