webpack + Babelで始める新しいJavaScript - 2

前回はwebpackとBabelをインストールするところまで完了しました。
実際にES2015の記述を書いてトランスパイルする前に、ES2015で追加された仕様についてよく使うものを紹介いたします。

追加された仕様1 『letキーワード』『constキーワード』

『let』『const』は変数定義時に使用するキーワードで、ブロック内でのみ有効な変数(ブロックスコープ)にしたり、再代入ができない変数にしたりと、より厳密に使い分けられることなります。ひとまず『let』は再代入可能、『const』は再代入不可と覚えていただけると問題ないと思います。

使い方は、varの使い方と同じで、以下のように記載します。

キーワード 変数名 = 値

実例を挙げます。

ブロック内でのみ有効な変数の例

JavaScriptでは波括弧で囲まれた範囲を『ブロック』と呼び、letとconstは、このブロック内でのみ参照可能な変数を定義することができるのです。これを『ブロックスコープ』と呼び、誤って同一の変数名を定義してバグが発生することも防げます。

ブロックスコープの例

{
  var a = 123;//varなので同一関数内なら参照可能
}
{
  const b = 135;//constなので{ }の範囲でのみ有効
}
{
  let c = 246;//letなので{ }の範囲でのみ有効
}
console.log(a);//var キーワードで定義されているので、123がコンソールに表示される
console.log(b);//ブロックスコープの外なので変数bを参照できない
console.log(c);//ブロックスコープの外なので変数cを参照できない

例は変数a、変数b、変数cを定義し、内容を順番にコンソールに出力するスクリプトですが、変数bを出力しようとした時点でエラーが出ます。変数bがconstキーワードを使ってブロックスコープ内で定義された変数であるため、ブロックの外では定義されていないことになっているためです。

追加された仕様2 『アロー関数』

ES2015からはアロー関数が使えるようになりました。ES2015でいうアロー関数とは、関数の定義を短く書けるようにしたもので、次のように書きます。

アロー関数式

(val) => {
  return val
}

これまで無名関数を使った場合に、関数内のthis変数の参照先がわかりづらくなる問題がありましたが、アロー関数を使うことで解決できます。イベントからthisを参照した時の違いは比較的わかりやすいと思いますので、例を挙げて概要を紹介いたします。

無名関数でイベントを定義した場合


var A = function (str) {
  this.message = str;
  document.body.addEventListener('click', function(){
    console.log(this);//consoleにはbody要素が表示される。
  })
}
var App = new A('無名関数でイベント追加');//Aをインスタンス化

上記スクリプトでは、Aをインスタンス化する際に「『this』の内容をコンソールに出力する関数」をbody要素のクリックイベントに追加しています。インスタンス化しているので、本来『this』は、インスタンス自身を参照しているはずですが、コンソールにはbody要素が表示されてしまいます。

無名関数でイベントを追加したらコンソールにターゲット要素が表示される

thisは呼び出し元によって参照先が変わります。イベント呼び出しの場合、イベントの対象要素がthisに代入される仕様になっているため、コンソールにはbody要素が表示されてしまうのです。

アロー関数でイベントを定義した例


var A = function (str) {
  this.message = str;
  document.body.addEventListener('click', ()=>{
    console.log(this);//consoleにはインスタンス自身が表示される。
  })
}
var App = new A('アロー関数でイベント追加');//Aをインスタンス化

上記スクリプト先の例と同じように、Aをインスタンス化する際に「『this』の内容をコンソールに出力する関数」をbody要素のクリックイベントに追加しています。アロー関数で定義した場合には、コンソールにインスタンス自身が表示されます。

アロー関数でイベントを追加したらコンソールにインスタンスが表示される

追加された仕様3 テンプレート文字列

変数に文字列を定義する際に、改行や、別の変数の内容を使いたい場合があると思いますが、テンプレート文字列を使うことで可能になります。
これまで、文字列は、「’(シングルクォート)」もしくは「”(ダブルクォート)」で囲むこと定義していました。それを「`(バッククォート)」にすることで、定義したい文字列内に改行を記載することが可能になります。
文字列内で別の変数の内容を使う場合には、使用する変数名を波括弧で囲み、括弧の前に$記号を置いて記載します。次のような形で使用します。


var A = 'テンプレート内で使いたい文字列';
var B = `テンプレート文字列の例
${A}
テンプレート文字列ここまで`;
console.log(B);

追加された仕様4 『import/export』

スクリプトを一つのファイルにして、読み込んだり、読み込ませたりすることが可能になる構文です。ライブラリを使う前提で書かれているスクリプトなどで使われます。以前は、一つひとつのjsファイルをscript要素で読み込ませて対応していたと思いますが、jsファイル内で完結させることが可能になりました。ES2015で最も注目された機能だと感じています。

以前の書き方

html


<!DOCTYPE html>
<html lang="ja">
<head>
  <meta charset="UTF-8">
  <title>ライブラリを読み込む</title>
  <script src="./js/library1.js"></script>
  <script src="./js/library2.js"></script>
  <script src="./js/library3.js"></script>
  <script src="./js/library4.js"></script>
  <script src="./js/library5.js"></script>
  <script src="./js/script.js"></script>
</head>
<body>
</body>
</html>
  

script要素でjsを指定して、各ライブラリの核となるオブジェクトをグローバル変数に登録することで使用する。

ES2015での書き方

JavaScript


import library1 from './library1.js'
import library2 from './library2.js'
import library3 from './library3.js'
import library4 from './library4.js'
import library5 from './library5.js'

const App = function () {
  console.log('complete!!');
}
App();

ES2015の書き方をする場合の注意点としては、export文が使われていないスクリプトをimportできない点です。たとえば、上記例で、library1.jsを読み込んでいますが、library1にexport文が無ければ、読み込ませることができません。export文は次のように書きます。

文字列「library1!!」を返す外部モジュールの例


export default function (){
  return 'library1!!';
}

例のような単純なスクリプトの場合は、あまりモジュール化の恩恵はありませんが、Webアプリケーションを作る場合などに役に立ちますので、覚えておいて損はありません。
import/export文については量が多いので、ここでは簡単な紹介にとどめさせていただきます。

まとめ

ES2015でよく使う仕様を紹介いたしましたが、トランスパイルまでたどり着けませんでした…。次回は実際にトランスパイルさせてみます。

Babelのトランスパイルは、import/exportを現時点(2017年11月現在)でブラウザが解釈できる形への変換に対応していないので、webpackなどモジュールバンドラを使うことで対応します。

簡単な例であればBabel公式サイトのTry it outで試すことも可能です。実際にどのようにES2015のスクリプトをどのように書き換えてブラウザに対応させるのか勉強になりますのでおススメです。どうぞ一度ご覧ください。

すべての人にインターネット
関連サービス