2016年3月14日月曜日

ECMAScript2015 (ES6) のまとめ / let, template string, arrow function

mainpicture

これをお読みの方は、どんな言語を用いて開発を行っているでしょうか。

javascriptはひと昔前までは主にブラウザ上で動きをつけるために利用され、私の感覚からするとその頃はとても書きにくい理解しづらい言語でした。(自分のプログラムの能力のせいもありますがw)しかし、nodejsが流行り始めた5,6年くらい前くらいからjavascriptはかなり勢いを増し、現在でもその勢いは大きく落ちることなく、結果多くの方が利用するようになっているのではないかなと思います。

最近ではnodejsも多くのPaaSの上で動作することが可能となり、バックエンドがjavascriptで記述することができるようになったため、フロントエンドとバックエンドで使用する言語を同一にするという目的のためにjavascriptを選択するのも良い選択になりました。

さらに、フロントエンドの開発が進んでいくうちにAngularJSreactといった数々のフレームワークが生まれ、SinglePageApplicationという考え方が生まれました。これらのフレームワークは今でも積極的にアップデートが重ねられ、リッチなWebアプリケーションを構築する際に大きく役に立ちます。

しかし、通常のjavascriptを利用して開発を行うと、言語仕様のために記述がしにくい箇所がでたり、冗長になったり、ソースコード量が多くなってしまうことがありました。それらを補うためにcoffeescripttypescriptなどが開発されるようになりました。

しかし昨年ECMAScript2015が制定され、ChromeやSafariなどの多くのブラウザによる実装が進んでいるため、coffeescripttypescriptで行われていた多くの部分を標準仕様で解決することができるようになりました。一部実装していないブラウザに関してはトランスパイラと呼ばれるES6をES5に変換するBabelのようなものもあるため、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

さて、少しずつみていきましょう。


let

ES5では変数宣言の際には

// ES5
var s = "I'm string"
var i = 123

このような形で定義していましたが、スコープが大きくなってしまうという問題がありました。

// ES5
function m() {
  var s1 = "s1";
  console.log(s1); // s1
  if (true) {
    var s1 = "changed";
    console.log(s1); // changed
  }
  console.log(s1); // changed
}
m();

これをlet宣言を使うことによりスコープをレキシカルブロック({}で囲まれた範囲)に宣言することができるようになりました。

// ES6
function m() {
  let s1 = "s1";
  console.log(s1); // s1
  if (true) {
    let s1 = "changed";
    console.log(s1); // changed
  }
  console.log(s1); // s1 ←変わらない!
}
m();

これでかなりスコープを限定して記述することが可能になりました。

swiftだとletは再代入不可ですが、ES6のletは再代入が可能です。
ES6の定数はconstで宣言します。


template string

これは他の言語にも良くある形だと思います。文字列フォーマットとも呼ばれているかもしれません。(厳密には文字列フォーマットは数値・文字の判別や数値の桁数などができるので違うかもですが)

// ES6
let pc = "Mac";
console.log(`I'm using ${pc}.`); // I'm using Mac.

こんな形で文字表現がかなり読みやすくなりました。これまでは+で連結しまくっていたので非常に楽です。


arrow function

むしろ今までなくて良くやってこれたなという雰囲気すら感じますが、関数宣言のシンタックスシュガーといえば良いでしょうか。

他の言語だとjava8から実装されたため同様の記法がjava8から使うことができ、Swiftにも同じような構文があります。RubyのProcオブジェクトやブロックとも似ています。

javascriptという性質上サーバーサイドとの連携が多く、遅延が発生するためそういった箇所はcallbackの嵐となるため、それをシンプルに書けるようにするためにはこのarrow functionが欲しくなってきます。

さて、どういったものなのかというと

// ES6
let f = () => {
  console.log("f is called");
}
f(); # f is called

これですね。少しややこしいケースも書いてみましょう。

// ES6
function post(data, callback) {
  setTimeout(() => {
    console.log(`Handle Data: ${data}`);
    callback({isOK: true});
  }, 3000);
}

function postDataToServer(data, callback) {
  post(data, callback);
}

function webapi(data, callback) {
  postDataToServer(data, callback);
}

console.log("Before Post");
webapi("Post Data", (response) => {
  console.log(response.isOK ? "Succeed!!" : "Failed...");
});
console.log("After Post");

このような形で時間のかかる処理(この例だとpost)の処理結果をcallbackが引き受けて、それをarrow functionで定義しておくとソースコードは短くてすみます。

別に読みにくければfunctionで代入も可能です。

// ES5
webapi("Post Data", function(response) {
  console.log(response.isOK ? "Succeed!!" : "Failed...");
});

これでもやっていることは全く変わりません。

ライブラリとかだと、第一に引数にerrorを渡し戻すものも多く存在します。また、この例のようにメソッドが一つくらいであればいいのですが、successとfailで二つのfunctionを定義しなくてはならなくなると徐々にめんどくさくなってきたりします。


さて、いかがでしたでしょうか。

今もまだ昔のjavascriptの書き方をしているのであれば、これを機に少しずつES6の書き方に変えていくのが良いかと思います。
次回は関数へのパラメータ周りを紹介していきます。

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

0 件のコメント:

コメントを投稿