泉水翔吾

ECMAScript 2015(ES6)の概要と次世代JavaScriptの新たな機能

 この記事は「ECMAScript2015/ES6特集」の第1回目です。この特集ではJavaScriptの次世代仕様であるECMAScript 2015(ECMAScript 6)を取り上げ、歴史や経緯から追加された機能や文法の詳細など複数回に渡って解説していきます。

ECMAScriptとJavaScript

 そもそもECMAScriptとはなんでしょうか?JavaScriptとは一体何が違うのでしょうか?ECMAScriptとJavaScriptの関係は、JavaScriptが生まれた1995年まで遡ります。

 JavaScriptは1995年、当時Netscape CommunicationsにいたBrendan Eich氏がWebで実行できるスクリプト言語として開発しました。その後Internet Explorerに搭載されWebの普及と共に浸透していきますが、当初はブラウザベンダーによる独自の拡張が多く互換性は低いものでした。そこで、Ecmaインターナショナルが中心となり、JavaScriptの中核仕様を抜き出して標準化したのがECMAScriptです。

ecmascript2015

 つまり、ECMAScriptはJavaScriptの言語仕様であり、JavaScriptはECMAScriptの仕様に基づいた言語のひとつということになります。他のECMAScriptを実装している言語としては、ActionScriptやJScriptなどがあります。

ECMAScript 2015とECMAScript 6

この連載で解説していくのは、先日策定されたECMAScript(ECMA-262)の6th editionです。ECMAScript 6th editionの6を取ってECMAScript 6(ES6)と呼ばれていますが、正確な呼称をECMAScript 2015(ES2015)とし、今後は年単位のより細かいリリースを計画しているようです。

 以降、本記事ではES2015と統一して表記しますが、リンク先がES6になっていたりすることもあります。

ES2015に追加される仕様

 ES2015には、非力であったこれまでのJavaScriptに対して文法や機能が多く追加されており、より安全で便利なプログラム言語に進化しています。ES2015の仕様は公式ホームページに掲載されていますのでチェックしてみましょう。

 ES2015から追加された機能を確認するには次のリソースが参考になります。特に後者は、ES6の機能とそれをES5以前で実装した場合にどうなるかのサンプルが比較されており、とても参考になります。

 今回はこの中から主な新機能を、シンタックスとオブジェクトの2つに分けて紹介していきますので、「ES5でこのように書いていたものが、ES2015ならこう書ける!」というのを感じてもらえればと思います。

ES2015の新たなシンタックス

 ES2015には、変数や関数の宣言・変数の代入・引数の展開・ジェネレータ関数など、実に多くの新しい文法が追加されています。

  • letconstキーワードによる変数宣言
  • classキーワードによるクラス宣言
  • 関数の引数のデフォルトパラメータ(Default Parameters)
  • 関数の可変長引数(Rest Parameters)
  • アロー関数(Arrow Functions)
  • ジェネレータ関数(Generator Functions)
  • 配列展開(Array Spread)
  • 分割代入(Destructing Assignment)
  • 文字列のテンプレートリテラル(Template Strings)
  • importexportによるモジュール構文(Module)

letとconstによる変数宣言

 ES5以前のJavaScriptには関数スコープしか存在せず、馴染みの深いvarによる宣言はしばし事故を招き、関数スコープを利用するために、無名関数を使ったスコープ作成の記述を用いることがしばしばありました。これに対し、letconstによる変数宣言ではブラケット{}によるブロックスコープが有効になります。

 constは定数を宣言したいときに使うキーワードであり、宣言された変数には、宣言時を除いて値の代入が不可能であるという性質を持ちます。varによって宣言した変数は命名などで工夫していても常に値が書き換わるリスクを孕んでいます。しかしconstで宣言された定数に値を再代入しようとすると、例外が発生しプログラムの実行はストップし、値の不変性がプログラムレベルで保証されます。

classによるクラス構文

 JavaScriptでnewを伴うオブジェクトの作成をするには、以下のように関数を宣言することで「クラスのようなもの」を実現してきました。このES5を使ったクラス表現はnewを使わずとも関数として呼び出すことが可能であるため、グローバル変数を書き換えてしまうリスクを常にはらんでいます。これをES2015のclassを使って書き直してみます。

 ES2015のclassを使って宣言されたHumannewキーワードなしで使うことはできないので、より副作用がない形でクラスを宣言可能になっています。

アロー関数による関数宣言

 functionを使った関数の定義に加えて、ES2015からはアロー関数が使えるようになります。functionというキーワードを使わずに=>を使って宣言することが可能になります。さらに、関数本体が単一式である場合はブラケット{}returnも省略できます。

 functionが省略可能になることでよりシンプルに書けますが、アロー関数は宣言しているスコープのthisを引き継ぐという特徴があります。もちろんこの機能も魅力のひとつですが、気にせずに使っていると思わぬミスをしてしまうかもしれません。

ES2015に追加されるオブジェクト

 シンタックス以外にも、様々な機能を備えたオブジェクトが追加されます。新たに追加されるオブジェクトの他にも、ArrayやObjectといった既存のオブジェクトに対して様々な関数が追加されており、機能が強化されています。

  • Promise: 非同期処理を抽象化するデザインパターン
  • Symbol: ユニークな値を表現する新たなプリミティブ型
  • Reflect / Proxy: オペレーションに処理を介入させる機能
  • Set / WeakSet: 一意なデータスタックを表すオブジェクト
  • Map / WeakMap: Key-Valueのデータ構造を表すオブジェクト

Promise

 Promiseは既にお馴染みの人も多いでしょう。JavaScriptのコールバック地獄に対する解決策のひとつとしてJavaScriptの世界に持ち込まれたPromiseは、需要も高くライブラリ実装も多かったですがES2015からはついにネイティブに組み込まれます。

 最近ではService WorkerやFetchなどの様々なブラウザAPIがPromiseベースで設計されており、今後もPromiseは多く使われていくでしょう。今のうちにマスターしておきたいところです。

Symbol

 Symbolはユニークな値を表現するプリミティブな新しい型です。Symbol型の値はStringのようにプロパティのキーとして使うことができますが、文字列とは異なりSymbolのインスタンスを使わないと参照することができません。

ProxyとReflect

 Proxyはオブジェクトへのアクセス時に処理を割り込ませる機能を提供するオブジェクトです。Proxyを使うと、値の参照時(get)や代入時(set)、プロパティの削除時などのタイミングで処理を介入させることが可能です。

 Proxyを使ってインターセプトすると、デフォルトの振る舞いを邪魔することになります。そこで、デフォルトの挙動を再現するためにReflectというオブジェクトがあります。Reflectにはインターセプトできるハンドラ(ここでいうgetset)に対応したメソッドが用意されているので、それを呼び出してやることでデフォルトの挙動を再現することができます。

MapとSet、WeakMapとWeakSet

 SetMapは、これまで配列やオブジェクトを使って表現していたデータスタックやKey-Valueといったデータ構造化をサポートします。Setのインスタンスには同一の値を追加できず、ユニークな値がスタックされていることが保証されます。MapはObjectのようにキーとそれに対する値を保持しますが、Objectと異なるのはキーに文字列以外のオブジェクトを指定できる点です。これによって様々なオブジェクトに対して値を関連付けることができます。

 WeakSetWeakMapはその名の通り、弱いSetMapです。SetMapに比べて参照が弱くなっており、値への参照が存在しなくなるとエントリが自動で削除されるという特徴があります。例えばDOMのオブジェクトに対してWeakMapを使って値を関連付けます。そこでキーに指定したDOMオブジェクトを削除すると、関連付けた値を参照する手段はなくなるため関連付けたKey-Valueのエントリは自動で削除されるのです。Objectで表現していた場合はどこからも参照されないエントリが残ることになるのでメモリリークの要因になりますが、WeakMapを使うことでそのリスクを減らしていけるでしょう。

まとめ

 第一回ではECMAScriptとJavaScriptの歴史、ES2015に追加される機能の概要、主な機能の紹介をしました。次回は各ブラウザの実装状況や、実践導入に向けて抑えておくべき知識などを解説していきます。

'; js_seriesContent.className = "js_seriesContent"; js_seriesContent.innerHTML = js_seriestitle.innerHTML; js_seriesContent.appendChild(js_serieslist_ul); if ( js_parent.lastChild == js_superior ) { js_parent.appendChild(js_seriesContent); } else { js_parent.insertBefore(js_seriesContent, js_superior.nextSibling); } if (js_serieslist_li_length > 5) { document.getElementsByClassName('moveToSeriesTop')[0].style.display = 'block'; document.getElementsByClassName('moveToSeriesTop')[0].href = document.getElementsByClassName('seriesmeta')[0].getElementsByTagName('a')[0].href; } })(this, this.document); // ソーシャルボタンをクリックされたらgaに送信 var elements, i; elements = document.querySelectorAll('.sns-buttons > li > a.facebook-btn-icon-link'); for (i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { ga('send', 'social', 'Facebook', 'like', '/1000ch/16984/'); }, false); } elements = document.querySelectorAll('.sns-buttons > li > a.twitter-btn-icon-link'); for (i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { ga('send', 'social', 'Twitter', 'tweet', '/1000ch/16984/'); }, false); } elements = document.querySelectorAll('.sns-buttons > li > a.google-plus-btn-icon'); for (i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { ga('send', 'social', 'Google+', '+1', '/1000ch/16984/'); }, false); } elements = document.querySelectorAll('.sns-buttons > li > a.hatena-btn-icon'); for (i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { ga('send', 'social', 'Hatebu', 'bookmark', '/1000ch/16984/'); }, false); } elements = document.querySelectorAll('.sns-buttons > li > a.pocket-btn-icon'); for (i = 0; i < elements.length; i++) { elements[i].addEventListener('click', function() { ga('send', 'social', 'Pocket', 'bookmark', '/1000ch/16984/'); }, false); }

週間PVランキング

新着記事

Powered byNTT Communications

tag list

アクセシビリティ イベント エンタープライズ デザイン ハイブリッド パフォーマンス ブラウザ プログラミング マークアップ モバイル 海外 高速化 Angular2 AngularJS Chrome Cordova CSS de:code ECMAScript Edge Firefox Google Google I/O 2014 HTML5 Conference 2013 html5j IoT JavaScript Microsoft Node.js Polymer Progressive Web Apps React Safari SkyWay TypeScript UI UX W3C W3C仕様 Webアプリ Web Components WebGL WebRTC WebSocket WebVR