JavaScriptのES6での変更点を今更ながら整理してみた

JavaScriptのES6での変更点を今更ながら整理してみた

これまで、ES6における変更点をきちんと整理できていなかったので、今更ながら整理しておこうと思います。
なお、本記事の執筆にあたり、JavaScript本格入門を参考にさせていただきました。ご存知の方は多いと思いますが、とても良い本です。
また、当然ながら全ての変更点を網羅できているわけではなく、最低限知っておきたいレベルのものを勝手に選定しました。
ES5とES2015の構文をそれぞれ羅列して必要に応じてコメントを書く、といった形で記載しています。
それでは、さっそくみていきます。

プロトタイプベースからクラスベースのオブジェクト指向構文へ

【ES5】

//クラスの定義
var Triangle = function(bottom , height){
this.bottom=bottom;
this.height=height;
this.getArea = function(){
return this.bottom*this.height/2;
};
};
//インスタンスの生成
var triangle = new Triangle(3,8);
console.log(triangle.getArea()); //12が出力される
}
//クラスの定義
var Triangle = function(bottom , height){
this.bottom=bottom;
this.height=height;
};
//メソッドはプロトタイプで宣言する
Triangle.prototype.getArea=function(){
return this.bottom*this.height/2;
}
//インスタンスの生成
var triangle = new Triangle(3,8);
console.log(triangle.getArea()); //12が出力される

ES5でオブジェクト指向構文を書くには、上記の2通りの方法があります。
どちらも、クラスを関数として記述していることに特徴があり、この点が、もともとクラスベースのオブジェクト指向を持つ言語(C++、Java等)でプログラミングしていた人が違和感を感じる箇所だと思います。
上と下の違いですが、上の場合はインスタンスごとに関数のメモリを確保してしまいメモリの無駄が多くなるため、下の書き方のようにメソッドはプロトタイプで宣言するのが通例なようです。(これが、JavaScriptのオブジェクト指向がプロトタイプベースのオブジェクト指向と言われている所以ですね。)
が、、どこからどこまでがクラスの内容なのかわかりにくいですね。
【ES6】

//クラスの定義
class Triangle{
//コンストラクター
constructor(bottom,height){
this.bottom=bottom;
this.height=height;
}
//メソッドの定義
getArea(){
return this.bottom*this.height/2;
}
}
//インスタンスの生成
var triangle = new Triangle(3,8);
console.log(triangle.getArea()); //12が出力される

これに対して、ES2015ではすっきりしている(他の言語のクラス定義と同様にかける)ことがわかります。

関数の書き方の改善(アロー関数)

【ES5】

var getArea=function(bottom,height){
return bottom*height/2;
}
console.log(getArea(3,8));//12が出力される

【ES6】

var getArea=(bottom,height) =>{
return bottom*height/2;
}
console.log(getArea(3,8));//12が出力される

“function”から”=>”の記載に変わり、少しだけ記述が楽になりました。

import/exportによるモジュール化

他の言語ではよくある、モジュール化がようやくES2015からサポートされました。
【ES6】
■exportする側(ModuleTest.js)

//クラスの定義
export default class Triangle{
//コンストラクター
constructor(bottom,height){
this.bottom=bottom;
this.height=height;
}
//メソッドの定義
getArea(){
return this.bottom*this.height/2;
}
}

先ほど定義したクラスに、”export default”を追記するだけです。defaultは、「importする際に特に指定がなければそのクラスや関数を呼ぶ」というもので、importする側でクラスを直接指定する場合は不要ですが、今回の例のようにファイルごとimportする場合は必須です。
■importする側

//ファイルのimport
import Triangle from './ModuleTest';
//インスタンスの生成
var triangle = new Triangle(3,8);
console.log(triangle.getArea()); //12が出力される

ちなみに、importとは別にrequireを使う方法もあり、はじめは違いがよくわからなかったのですが、調べてみると機能としては変わらなさそうです。(requireはnode.jsの書き方でimportはes2015から使えるようになった書き方とのこと)
requireを使用する場合は、以下のようにimportとは微妙に書き方が異なります。が、どちらの書き方が楽とかいうのはなさそうで、ここは好みなのかなぁという印象です。
■exportする側※requireを使う場合

//クラスの定義
module.exports = class Triangle{
//コンストラクター
constructor(bottom,height){
this.bottom=bottom;
this.height=height;
}
//メソッドの定義
getArea(){
return this.bottom*this.height/2;
}
}

■importする側※requireを使う場合

//ファイルのimport
var Triangle = require('./ModuleTest');
//インスタンスの生成
var triangle = new Triangle(3,8);
console.log(triangle.getArea()); //12が出力される

let/constによる変数/定数の宣言

変数を宣言する際、これまではvarを使用していたと思いますが、ES2015では新たに追加されたletを使用することが推奨されています。
なぜかというと、varだと変数のスコープが限定されず下記のプログラムでも普通に通ってしまいます。
【ES5】:varを使った場合

if(true){
var test=5;
}
console.log(test); //5が出力される

一方で、letを使った場合はブロック内の変数をブロック外で使うと、きちんとエラーを出力してくれます。
【ES6】:letを使った場合

if(true){
let test=5;
}
console.log(test); //エラーとなる

「スコープはできる限り限定すべき」という一般的な感覚に基づけば、こちらを使った方が良いです。
constは、定数を宣言するときに使います。constはES2015以前でも一部のブラウザでは使えたようですが、標準化されたのはES2015になってからです。
具体的な使い方はここでは割愛します。

テンプレート文字列

【ES5】

var name ='山田';
var sentence = 'こんにちは'+ name + 'さん。\n元気でしたか?';
console.log(sentence);

【ES6】

let name = '山田';
let sentence = `こんにちは${name}さん。
元気でしたか?`;
console.log(sentence);

テンプレート文字列を使うことで、”文字列への変数の埋め込み”や”文字列を複数行で書く”ことが可能になります。
ES5では、前者を行うには文字列の連結、後者を行うには改行コードの記述が必要だったので、地味にすごく便利な変更だと思います。
ちなみに、テンプレート文字列を使うにはシングルクォート/ダブルクォートではなくバッククォートでくくる必要があります。入力にはShiftキー+@キーを使います。
※上のプログラムでバッククォートが正しく表示されていませんね。WordPressの標準の機能でそうなってしまうようですが、解決策を探して改善します。

まとめ

今回は、ES6での変更点で重要そうなものをまとめてみました。記述しやすくなっていたり、欲しかった機能が追加されていたりするので、便利なものはどんどん使っていこうと思います。
今回あげたもの以外にも、配列を扱うためのfor..of構文や、連想配列を扱うためのMapオブジェクト、非同期処理の状態を監視するPromiseオブジェクト等も便利そうなので、引き続き勉強していこうと思います。それではー!