Javascriptは分かるけど、ES6(ES2015)はイマイチ分からない…ということで、ES6で新たに追加された機能や構文を学ぶために参考になった記事をまとめてみました。
develop or drink ? ©
当記事ではBabelの「Learn ES2015」のトピックに合わせて和訳したものをまとめてみたいと思います。
目次
Babelとはなにか
Babelは、ブラウザにまだサポートされていないようなJavaScriptの次世代の標準機能を、現在のブラウザでも使えるようにする機能(=トランスパイラ)をNode.jsで使えるようにしたもの。BabelのホームページではJavascriptの次世代標準機能を「Learn ES2015」で紹介しています。
また、ES6を学ぶには下記の書籍も参考になります。
ES6と各ブラウザや各言語の対応状況
各ブラウザやNode.jsなどの各言語への対応状況はECMAScript 6 compatibility tableで随時確認することができます。
Arrows and Lexical This
関数をアロー演算子(=>
)で書けるようになりました。
arrow.js1 2 3 4 5 6 7 8 9 10 11 12 13
| let exampleFunction = (v1 , v2) => { return v1 + v2 }
let exampleFunction2 = v => v + 1
console.log(exampleFunction(1 ,2)) console.log(exampleFunction2(1))
|
class
クラスの定義とクラス定義ができるようになりました。
class.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22
| class Hoge{ constructor(fuga){ this.fuga = fuga; } piyo(){ alert(this.fuga); } }
var hoge = new Hoge('FUGA'); hoge.piyo();
class HogeSub extends Hoge{ constructor(fugaSub){ super(fugaSub); } piyoSub(){ super.piyo('classの継承'); } } var hogeSub = new HogeSub('できました!'); hogeSub.piyoSub();
|
LIG
ES6の新機能「class構文」 – 基礎編
ES6のClassについて分かりやすく解説されている
Enhanced Object Literals
オブジェクトのキーを動的に定義することができるようになりました。キーは従来の文字列以外に、変数などで指定できます。
enhancedObjectLiterals.js1 2 3 4 5 6 7 8 9
| let arrName = "test"
let ob = { arrName : 1 , [arrName] : 2 }
console.log(ob.arrName) console.log(ob.test)
|
れおの備忘録
Babel: ES6で動的なオブジェクトプロパティをリテラルで定義する方法
Template Strings
文字列の扱いが従来よりも便利になりました。
string.js1 2 3 4 5 6 7 8 9
| console.log(`文字列`.length)
console.log(`文字列 改行もできる`.length)
let s1 = "1文字目", s2 = "2文字目"; console.log(`文字列に${s1}と${s2}を埋め込む`)
|
Destructuring
分割代入ができるようになりました。
destructuring.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| let [a, ,b] = [1,2,3] console.log(a === 1) console.log(b === 3)
let { op: a, lhs: { op: b }, rhs: c } = getASTNode()
let {op, lhs, rhs} = getASTNode()
let g = ({test: x}) => console.log(x) g({test: 5})
let [a] = [] console.log(a === undefined)
let [a = 1] = [] console.log(a === 1)
let r = ({x, y, w = 10, h = 10}) => x + y + w + h console.log( r({x:1, y:2}) === 23 )
|
Default + Rest + Spread
関数の引数の定義方法が増えました。
defaultRestSpread.js1 2 3 4 5 6 7 8 9 10 11
| let fn1 = (x, y=12) => x + y console.log( fn1(3) == 15 )
let fn2 = (x, ...y) => x * y.length console.log( fn2(3, "hello", true) == 6 )
let fn3 = (x, y, z) => x + y + z console.log( fn3(...[1,2,3]) == 6 )
|
Let + Const
新たに変数宣言としてlet
やconst
が使えるようになりました。
analogic
var, let, constの使い分けについて
Iterators + For..Of
配列などの要素を、従来よりも簡単に取り出せるようになりました。
Iterator(イテレータ)とは、配列などのコレクションの要素を、一つずつ順番に取り出すことのできる性質をもったもののことです。また取り出せる性質を持っているオブジェクトをイテラブルなオブジェクトと呼んでいます。
ES6ではイテレータ、イテラブルという用語が度々登場してくるので、しっかり覚えて置いたほうが良さそうです。
Qiita
JavaScript の イテレータ を極める!
イテレータとは何か?またその使い方を分かりやすく噛み砕いて解説している。またFor Ofや配列や文字列がイテラブルなオブジェクトである事が触れられているなど、理解を深めやすい内容となっている。
Iterators.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
| let arr = [ 1 ,2 , 3] for(let elm of arr){ console.log(elm) }
let arr2 = ["A", "B", "C"]; for(var v of obj.keys()) console.log(v);
for(var v of arr2.entries()) console.log(v);
|
ES6では、イテレータの処理内容を自由に定義する事もできます。以下は偶数を返すイテレータの例です。
Iterators2.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| let fibonacci = { [Symbol.iterator]() { let pre = 0; return { next() { pre = pre + 2; return { done: false, value: pre } } } } }
for (var n of fibonacci) { if (n > 10) break; console.log(n); }
|
Generators
イテレータの一種であり、イテレータをより強化したようなものです。1つの要素を取り出そうとするたびに処理を行い、要素を生成してくれる関数を定義します。
Qiita
JavaScript の ジェネレータ を極める!
ジェネレータとイテレータの違いが分かりやすく解説されている。またジェネレータの使い所や、yieldの使い方がサンプルコードで分かりやすく説明されている。
generator.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19
| var ary = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10]; for(var num of ary) console.log(num);
function* gfn(from, to){ while(from <= to) yield from++; }
var g = gfn(1, 10); for(var num of g) console.log(num);
|
yieldとは?
ジェネレータで使われるyield
は、記述した位置で実行を一旦停止して、その結果を返すものとなっています。
generator-yield.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30
|
function* gfn(n){ n++; yield n; n += 2; yield n; n = 0; yield n; }
var g = gfn(0); console.log( g.next() ); console.log( g.next() ); console.log( g.next() ); console.log( g.next() );
function* gfn2(){ yield* [1, 3, 5]; }
var g2 = gfn2();
console.log( g2.next() ); console.log( g2.next() ); console.log( g2.next() ); console.log( g2.next() );
|
Unicode
Unicodeリテラルが追加されました。サロゲートペア対象の文字列でも、従来のように分割せずに表記できるようになります。
Qiita
ES2015に追加、拡張された機能
サロゲートペアについては以下の記事が参考になります。
CodeZine
サロゲートペア入門
近年、Unicodeに組み込みたいという文字の要望がいろいろと増えてきました。結果的に従来の2バイト(65536文字)では文字が足りない状況になってしまったのです。そこで、解決策としてサロゲートペアという方法が導入されました。これは、「1文字=2バイト」の基本は維持しつつ、一部の文字については「1文字=4バイト」にする方法です。
unicode.js1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17
| console.log("𠮷".length == 2)
console.log("𠮷".match(/./u)[0].length == 2)
console.log("𠮷" == "\uD842\uDFB7") console.log("\u{20BB7}" == "𠮷")
console.log("𠮷".codePointAt(0) == 0x20BB7)
for(var c of "𠮷") { console.log(c); }
|
Modules
export文やimportを使用することで、関数やオブジェクトをエクスポートやインポートすることができます。
Think IT
ES2015のモジュール管理
モジュールとは何かという内容から始まり、モジュール管理の必要性を解説している
lib/math.js1 2 3 4
| export function sum(x, y) { return x + y; } export var pi = 3.141593;
|
上記のようにモジュールを定義しておき、下記のようにインポートします。
app.js1 2 3 4 5 6
| import * as math from "lib/math"; console.log("2π = " + math.sum(math.pi, math.pi));
|
default export
また、モジュール1つに対して1つのメンバーだけ、名前を指定せずにエクスポートすることができます。
lib/math2.js1 2 3
| export default function(x) { return Math.exp(x); }
|
app.js1 2
| import exp from "lib/math2"; console.log("e^π = " + exp(pi));
|
Map + Set
Mapはキーに対して値を保存しておけるものです。オブジェクト(Object
)と似ていますが、キーは文字列以外にも数値やオブジェクトを指定することができます。更に、
- 値の取得
- 値の存在確認
- データの削除
- キーの取得や値の取得
など、オブジェクトでよく行う処理を、シンプルに行えるようにメソッドが用意されているのも良い点です。
YoheiM.NET
JavaScript ECMAScript6のMapとSetを使ってみよう
Mapの使い方がシンプルに解説されていて理解しやすい
Setとは?
SetはMapと同様のメソッドが用意されています。
Mapと異なる点は、Setは配列を扱うものとなっている点です。また値の重複が許されないという性質を持っています。
Setで値を追加する際には、重複を気にせず値を追加する事ができる(重複した場合には値が新たに追加されない)ので、一意な配列データを扱いたい時に活用したい機能です。
WeakMap + WeakSet
WeakMapはMapと違い、オブジェクトの参照のみをキーに指定できます。また、キーに指定したオブジェクトの参照を開放する(例:obj = null
)とすると、WeakMapに格納したデータも消滅するという性質があります。
uhyohyo.net
Map クラスについて
「WeakMap とオブジェクトキーの参照関係について」の項目でWeakMapの使い方を分かりやすく解説している
javascript プログラミング講座
WeakSetとWeakMap
WeakMapとは何かについて、とても分かりやすい解説をまとめている。
(引用)keyとなるオブジェクトを汚さないというのがWeakMapの1つの利点。オブジェクトにプロパティとして勝手に付加する方式だと、外部からそれを書き換えられてしまう可能性もあります。WeakMapならば、それを持っている自分しか値を読んだり書き換えたりすることができず安全。
Proxies (proxy) + Reflect API
Proxyはオブジェクトの持っている機能(トラップ関数)に割り込み、独自に定義した命令を実行させることができます。
Qiita
【JavaScript】Proxyオブジェクトなるものを学ぶ
トラップ関数(補足タイプ)と、使い方については以下の記事が参考になります。
JS.next
Proxyについて
ReflectはProxyと同じメソッドを持ち、静的な関数を返します。上記の記事で解説されているように、ReflectはProxyの内部で、オブジェクトの本来の動作を再現する場合に使われる事が多いようです。
Symbols
既存のプログラムやメソッドに影響を与えないように、独自のメソッドを安全に作ったり拡張する事ができます。
JS.next
ECMAScript6にシンボルができた理由
Subclassable Built-ins
ArrayやDate、DOM Elementsなど、ビルトインクラスを継承し、サブクラスを作成することができるようになりました。
Think IT
ES2015に追加、拡張された機能 Subclassable Built-ins
Math + Number + String + Object APIs
Javascriptで今まで備わっていた標準ライブラリに、いくつか新機能が追加されました。
Math
- 常用対数
- 双曲線関数、逆双曲線関数
- 平方根、立方根、少数から整数、正負の符号
- ビット計算
Number
- イプシロン(ε)
- 有限数、整数、NaNの判定
- 文字列から浮動小数点数に変換
- 基数を元にした整数に変換
String
- 特定の文字列が存在するか判定
- 文字列の指定回数分の生成
Object
Array
- Array型への変換(
Array.from
) - 引数から新しいArrayを作成(
Array.of
) Arrayの指定範囲のコピー(Array.copyWithin
)
第2引数から第3引数までの範囲をコピーし、第1引数で指定した開始位置にコピーする
Arrayからkeyとvalueの組み合わせを取得(Array.entries
)
Think IT
既存の標準ライブラリ(Math/Number/String/Object/Array)に追加された新機能
Binary and Octal Literals
2進数(Binary数値)と8進数(Octal数値構文)が新たにサポートされました。それぞれ0〜1
、0〜7
までの数値を使うことになりますが、その範囲を超えた場合にはシンタックスエラーが出るようになっています。
MDN javascript - 字句文法
Numericリテラル
Promises
非同期処理を従来よりも単純で見通しの良いコードで記述できます。
Think IT
ES2015が備えるモダンな非同期処理
Promiseの使い方や、従来の記述方法と比較して、Promiseの良点を解説している。また新たに追加されたAsync/awaitについても単純なサンプルコードで分かりやすく解説されている。
Async / await
についてはnode.js 7.6以降からサポートされており、まだ対応状況は少なそうです。しかし、Promiseよりも更にシンプルに非同期処理を記述できるため、今後は活用されるシーンが増えそうです。
InfoQ
Node 7.6、async/awaitをデフォルトでサポート
Reflect API
Proxies (proxy) + Reflect APIの項目を参照。
Tail Calls
再帰関数で関数呼び出しの階数が深くなりすぎると、発生することのあるスタックオーバーフロー。これを解消する方法として末尾再帰(Tail Calls)変換があります。
ブラウザでは殆ど対応していないのが現状のようで、現在はBabelがトランスパイル(Javascriptに変換)してくれる場合に限り使えるようです。ES2015では再帰関数を末尾呼び出し最適化してくれます。
Qiita
末尾再帰による最適化
Babelの末尾呼び出し最適化について解説されている。また付録として多重再帰関数や相互再帰関数についても紹介されている
ということで
ES6で新たに追加された機能や構文を学ぶために参考になった記事をまとめてみました。ES6はJavascriptとは大分違っており、出来ることがかなり増えました。
まとめた私も、まだ全てをマスターしきれていない状況なので、こちらの記事を振り返りながら学んでいきたいと思います。また、ES6を学ぶには下記の書籍も参考になります。こちらもご覧ください。