2017.03.13 [月] そうだ、ECMAScript6(ES2015)でいこう
2017年もあっという間に、3月半ばですね。
講師のカワグチです。
今では、Webサイトには欠かせないJavaScriptですが、国際的なプログラミング言語を提供できるようにEcma Internationalによって標準化されています。
ECMA は、以前は European Computer Manufacturers Association〈欧州電子計算機工業会〉の頭文字をとったものでしたが、1994年にEcma Internationalに名称を改めました。
この標準化されたJavaScriptのバージョンはECMAScriptと呼ばれ、現在、バージョンは、ES5(ECMAScript5)が一般的です。
2015年にES6が標準化され、徐々にWebブラウザで利用できるようになってきました。
また、このES6から、仕様書の表題に2015が追加されたことにより、ES6(ES2015)と併記されることが多くなりました。
さらに、昨年6月にはECMAScript2016が標準化され、現在ECMAScript2017が策定中です。
今後は毎年新しく仕様が策定されるようになるということでES7....8...ではなく、ES2016, ES2017, ...と表記されていくようです。
参考:ES6 or ES2015 ? 〜WEB+DB PRESS Vol.87 ES6特集に寄せて〜 - Cybozu Inside Out | サイボウズエンジニアのブログ
Internet Explorer11は、あまり対応していませんが、iOS SafariやGoogle ChromeをはじめMicrosoft Edgeなどの最新のWebブラウザでは対応しています。
参考:ECMAScript 6 compatibility table
最近では、出版されるJavaScriptの入門書でもES6(ES2015)を解説したものも多くなり、インターネット上の情報も特に注記もなく、新しい仕様で解説されていることも増えました。
授業でも、今後はES6(ES2015)を盛り込んでいって良い時期かもしれません。
ということで、ES6で新しく追加された仕様を少し調べてみました。
目次
- ES6(ES2015)とは
- let(局所変数)
- const(定数)
- 引数の記法
- テンプレートリテラル
- アロー関数
let(局所変数)
JavaScriptで変数宣言はvarで行ってきましたが、ES6(ES2015)では、letが加わりました。
いままで使用してきたvarとの違いは、
- 再宣言ができない
- ブロックスコープ
実際にコードを見てみましょう。
再宣言ができない
var num = 12; // 変数を宣言(var)して代入 var num = 11; // 変数を再宣言(var)して代入 console.log(num); //11 再宣言した変数が有効 let value = 16; // 変数を宣言(let)して代入 value = 17; // 代入して値の変更 console.log(value); //17 値の再代入はできる let value; //変数の再宣言はできない let value = 18; //もちろん、代入もできない
varの場合は、再宣言することができましたが、letの場合は、再宣言をした場合エラーが返ってきます。
Uncaught SyntaxError: Identifier 'val' has already been declaredちなみに、varで宣言した変数もletでは再宣言できません。
「識別子 'val'はすでに宣言されています」
var value = 101; let value = 102; console.log(value); //Uncaught SyntaxError: Identifier 'val' has already been declared
ブロックスコープ
JavaScriptのvarには、グルーバルスコープとローカルスコープがあります。
varは関数(function)でスコープされ、if文やfor文ではスコープはされませんでした。
letでは、{ }(ブロック)でスコープすることができるため、if文やfor文ででも、ブロックの外側と内側で区別がつけられます。
var num = 201; if(true){ let num = 202; console.log(num); // 202 }; console.log(num); // 201
変数の巻き上げ(hoisting)
プログラムは上の行から順番に実行されていきます。
本来、変数などで定義されていない場合に、呼び出したとき「定義されていません」とコンソールにエラーが表示されます。
console.log(hoist);
Uncaught ReferenceError: hoist is not defined
「hoistは定義されていません」
ところが、同じスコープ内の下の行に変数を定義すると、undefined(値がありません)と表示されます。
「変数は宣言してあるけど、値が代入されてません」という意味で、これを変数の巻き上げ(hoisting)と呼んでいます。
console.log(hoist); //undefined var hoist = 'yes'; console.log(hoist); //yes
一見すると巻き上げていないようですが、letでも巻き上げはおこるようです。
let text ="global"; hoisting(); function hoisting() { console.log(text); // Uncaught ReferenceError: text is not defined at hoisting let text = 'local'; }
上記の場合、巻き上げがないとすれば、変数textの'global'がコンソールに表示されるべきですが、エラーが表示されるということは、ブロックの始めから変数宣言が実行されるまで、 "temporal dead zone(変数にアクセスできない領域、略してTDZ)" の中にありますが、変数は宣言されているということになります。
const(定数)
他のプログラム言語ではある定数もES6(ES2015)では加わりました。
letと同じような働きをしますが、特徴としては、
- 再宣言も再代入もできない
- ブロックスコープ
再宣言も再代入もできない
const num = 301; // 定数を宣言(const)して代入 console.log(num); //301 const num; //再宣言はできない //Uncaught SyntaxError: Missing initializer in const declaration. num = 302; //もちろん再代入もできません //Uncaught TypeError: Assignment to constant variable.
また、letと同じように巻き上げはおこります。
参考:const - JavaScript | MDN
引数の記法
ES6(ES2015)では、引数の仕様が大きく変更されています
引数のデフォルト値
ES6(ES2105)では、引数にデフォルト値(初期値)が設定できるようになりました。
function getRectangle(width = 2, height = 3){ return width * height; } console.log(getRectangle(5));
第1引数は5が入るのですが、第2引数は設定されていませんので、そのまま初期値の3がはいります。
- 15
可変長引数
ES5までは、argumentsオブジェクトを利用していました。
argumentsオブジェクトは、似ていますが配列ではありませんので、利用する場合コードが冗長になりがちでした。
参考:arguments - JavaScript | MDN
ES6(ES2015)では、仮引数の前に「...(ピリオド3つ)」と展開(スプレッド)演算子を付与することで、可変長引数(Rest Parameter)となります。
可変長引数とは、引数の長さを自由に変えられる引数のことで、“配列”として受け取ることができます。
よって、配列のメソッドが利用できますので、コードを簡略化することができます。
参考:Rest parameters - JavaScript | MDN
//ES5 引数の数値を順番に足していく function sum() { var result = 0; for (var i = 0; i < arguments.length; i++) { result += arguments[i]; } return result; } console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10)); //55 //ES6 引数の数値を順番に足していく function sum(...numbers) { return numbers.reduce(function(a, b) { return a + b; }); } console.log(sum(1, 2, 3, 4, 5, 6, 7, 8, 9, 10));
- 55
テンプレートリテラル(Template literal)
JavaScriptは、ほとんどのネイティブオブジェクト値を生成することのできる「リテラル」と呼ばれるショートカットを提供しています。
例えば、'(シングルクォテーション)や"(ダブルクォテーション)で囲まれた文字の並びは、文字列リテラルです。
ES6(ES2015)では、文字列を定義する新しいリテラルとしてテンプレートリテラルが導入されました。
変数埋め込み
テンプレートリテラルは`(バッククオート)で囲むことで、今まで+を使って連結していた変数を文字列に埋め込むことができます。
let name = 'trident'; console.log(`Hello, ${name}`) //Hello, trident
テンプレートリテラル中の${ }で囲んだ箇所には任意の式を記述できます。
その値が文字列として連結されます。
複数行文字列
テンプレートリテラルでは、改行を含む複数行の文字列をそのまま記述できます。
//es5 let tsit = 'トライデント \n\ コンピュータ \n\ 専門学校' console.log(tsit); //es6 let tsit = `トライデント コンピュータ 専門学校`; console.log(tsit);
- トライデント
コンピュータ
専門学校
タグ付きテンプレート
タグ付きテンプレートでは、関数を使ってテンプレートリテラルのアウトプットを調整できます。
最初の引数には“文字列リテラルの配列”を含み、2つ目とそれに続くそれぞれの引数は、“処理された(調理された)テンプレート代用式の値”です。
関数名は自由につけられます。
var a = 'Mike'; var b = 'Trident'; function tag(strings,...values) { //第1引数:strings, 第2引数:values console.log(strings,values); return ; } tag`Hello ${ a } world ${ b }`; //タグ付きテンプレート
- ["Hello ", " world ", "", raw: Array(3)]
- ["Mike", "Trident"]
参考:テンプレート文字列 - JavaScript | MDN
ちなみに、${}と${}の間に何も文字がない場合、空文字が渡されます。
${}から始まる場合はその前に空文字が、${}で終わる場合はその後に空文字があるものとして扱われます。
参考:テンプレートエンジン不要?JavaScriptで文字列処理を簡潔にするTemplate literal | HTML5Experts.jp
//${}と${}の間に文字がない tagFunc`xyz${'subst'}${'subst'}xyz` { templateObject: [ 'xyz', '', 'xyz' ], substs: [ 'subst','subst' ] } //${}から始まる tagFunc`${'subst'}xyz` { templateObject: [ '', 'xyz' ], substs: [ 'subst' ] } //${}で終わる tagFunc`abc${'subst'}` { templateObject: [ 'abc', '' ], substs: [ 'subst' ] } //何もない場合も空文字が入る tagFunc`` { templateObject: [ '' ], substs: [] }
参考:8. Template literals | Exploring ES6
アロー関数
省略記法
functionキーワードを使わずに関数式が書けるようになりました。
=> という記号が矢に見えることからアロー関数と呼ばれます。
//ES5 var add = function(a,b){ return(a + b); }; //ES6(ES2015) var add = (a , b) => { return(a + b); }; console.log( add(400, 1) ); //401
関数が式だけで表される場合、ブロックの波括弧{ }とreturnが省略できます。
var add = (a , b) => a + b; console.log( add(400, 1) ); //401
また、 引数を 1 個しか取らない場合、丸括弧 () は任意となります。
//正方形の面積 var square = n => n * n; console.log( square(21) ); //441
他にもクラスやPromiseなど、新しい便利な機能がありますが、とりあえず上記から少しずつ取り入れてくといいのではないでしょうか。
IE11のシェアが20%を超えていますので、そのまま利用できるのは、letやconstなど一部ですが、ES6(ES2015)の新しい文法を使ったソースコードを、ES5またはES3までの文法に置き換えるトランスコンパイラ(Babelが有名)などで変換したり、古い環境でも使えるようにするライブラリである、Polyfillを読み込みことで利用できます。
また、クラスやBabelの環境構築なども含めて記事にしていきたいと思います。
- 関連記事
-
- 「いいね!」ボタンをGoogleスプレッドシートとGASで作る (2024/01/03)
- JavaScriptで要素を挿入する。 (2023/09/30)
- map()?new Map? (2023/08/10)
- ポートフォリオサイトを印刷用CSSでプリントする。 (2022/03/05)
- @useの使い方がわからない…ので (2022/02/12)
- display:contentsを使ってみたい。 (2021/09/30)
- jQueryだっていいじゃない。 (2021/03/09)
- TypeScriptってなんだ?! (2021/03/01)
- CSSの単位 (2020/09/03)
- JavaScriptのclassについて、書いてみた。 (2019/12/30)