2016年3月22日火曜日

ECMAScript2015 (ES6) のまとめ / default parameter, spred operator, rest parameter

mainpicture

前回に引き続き、ES6の変更点を見ていきます。

より詳細を確認したい方はECMAScript2015の公式を確認すると良いかと。


ECMAScript2015のまとめ

ES5と比較した時のES6の特徴としては以下のものが挙げられます。(言語仕様を読むと他にもいろいろと定義はされています)

  • let
  • template string
  • arrow function ( => )
  • default parameter ( function(x, y=10) { )
  • spread operator ( ...[1,2,3] )
  • rest parameter ( function(x, y, ...z) { )(今日はここまで)
  • class
  • import, export
  • Promise
  • Set, Map

前回は新しいarrow functionや変数宣言の新しいスコープであるletなどを取り上げました。

今回は、関数へ渡す引数やパラメータ展開の話がメインになります。


default parameter

rubyやpythonに見られるデフォルト引数という仕様です。引数に値が渡されなかった場合にこちらの値を利用することになります。メソッドのオーバーロードを書かなくて済むという利点がありますが、実際にどんな引数が渡ってきているのかを把握しておかないと何故か動いてしまうというソースを書いてしまうことになりかねないので注意が必要です。

ES5で実現するためには関数内で引数を取得するargumentsと呼ばれるオブジェクトを利用したり、関数名を変えたりしていることかと思います。

// ES5
var checkarg = function(i1,i2) {
  console.log(i1) # 1
  console.log(i2) # 2
  console.log(arguments['2'] || 'def') # def
}
checkarg(1,2)

これを次のように書き換えることができるようになりました。

// ES5
var checkarg = function(i1,i2,i3='def') {
  console.log(i1) # 1
  console.log(i2) # 2
  console.log(i3) # def
}
checkarg(1,2)

Firefoxには実装済みのようですが、chromeとnodeでは動作が確認できませんでした。

このデフォルト引数は、スクリプト言語では割と有用だと個人的には思っています。確かにメソッド内部で値の存在判定を行い、デフォルト値っぽいのを使うことができるのですが、多少煩雑ですし何を意図しているのか分かり難い感じになってしまうため、これを使えるとソースコードが読みやすくなりますね。


spread operator

私がこの演算子に出会ったのはreact-nativeを使ってアプリを実装しているときでした。react-nativeのNavigatorSceneConfigsのtransitionで使われています。

var FadeToTheRight = {
  ...FadeToTheLeft,
  transformTranslate: {
    from: {x: 0, y: 0, z: 0},
    to: {x: Math.round(SCREEN_WIDTH * 0.3), y: 0, z: 0},
  },
  translateX: {
    from: 0,
    to: Math.round(SCREEN_WIDTH * 0.3),
  }
};

・v0.15だったので今は違うかもしれないですが。
・上の例はES7のproposalで、babelがpluginを用いて利用可能にしています。純粋なES6の実装では使うことができません。

...FaceToTheLeftというのが中にあるのが確認できます。FadeTransactionの基本的な設定のようなものが、FaceToTheLeftに定義されていて(遷移の最後のほうでopacityが減るなど)、FadeToTheRightで一部変更がある部分を定義していることになります。

もう少し簡単なspread operatorの例を挙げてみましょう。

// ES5
var array1 = [1,2,3]
console.log(array1);
var array2 = [4,5,6]
console.log(array2);

console.log(array1.concat(array2)); 

最後のarray1の連結部分が

// ES6
var array1 = [1,2,3]
console.log(array1); // [1,2,3]
var array2 = [4,5,6]
console.log(array2); // [4,5,6]

console.log([...array1, ...array2]) // [1,2,3,4,5,6]

と、こんな風に書くことができます。

かなり見通しよく書けるようになりました。割とこの辺りはlodashとかを利用して 書くことが多いのですが、標準仕様で使えるようになるとありがたいですね。


rest parameter

最後はrest parameterについてです。他の言語だと可変長引数で同様のことができるようになっていたりします。

むしろjavascript今までできなかったのかよ的な雰囲気すらあります。おそらくこれまではargmentsでどうにかしていたのでしょう。

こんな感じになります。

//ES6
function expose(a1, ...rest) {
  console.log(a1) // 1
  console.log(rest) // [2,3]
}
expose(1,2,3);

node5系で動作させる場合には、コマンドに「–harmony_rest_parameters」というオプションを入れる必要があります。
node --harmony_rest_parameters hogehoge.js

残りのパラメーターが配列で入ってくるのが楽ですね。長さを気にせず渡すことができます。
(あまり長すぎるのも可読性が落ちるので気をつけましょう。)


今回は引数に関して主にまとめてみました。個人的にはbabelで利用出来るspread operatorのhash版が結構使えるやつなのでオススメです。

特にreateを実装しているとstateを書き換える部分があるのですが、そこを読みやすくかけるので。

this.setState({
  ...this.state,
  field: newValue,
});

さて、次回からES6のクラスとモジュール周りをまとめていきます。

では良いインプットと良いプログラミングを。

0 件のコメント:

コメントを投稿