2019/3 JavaScriptの進化
今回は年々進化しているES2015以降のJavaScriptについてご紹介します。
JavaScriptとは
JavaScriptは、Netscapeが独自で始めたプログラミング言語で、各ブラウザベンダで動くようにECMAScriptという名前で標準化されました。しかし、慣習的に世の中ではECMAScriptと呼ばずJavaScriptと呼ぶことが一般的です。
このECMAScriptは、標準化団体によりプログラミング言語として1999年にバージョン3、2009年にバージョン5とアップデートしていました。 しかし、バージョンアップするのに非常に年月がかかったため、2015年以降はその年の間に新仕様で固まったものだけをアップデートする、毎年アップデート方式に変わりました。
そのため、2015年以降のJavaScriptバージョンは、ES2015(ECMAScript 2015)、ES2016という感じの略称で呼ぶようになってきました。
そしてES2015以降、知らない間に構文追加されているので、新しい記法で書かれたコードも読めるように以下でご紹介します。
ES2019
この年のアップデートは、あまり使い所がないかもしれません。
trimStart(), trimEnd()
// 空白文字の除去
' abc'.trimStart(); // => 'abc'
'abc '.trimEnd(); // => 'abc'
try catch引数省略可能に
try {
throw new Error('exception!');
} catch { // (error)を記述しなくてもいい
console.log('エラー');
}
ES2018
スプレッド構文は大変便利で、ReactのReduxでよく使いました。
Promise.finally
// ajax通信時のエラーハンドリングに便利
new Promise((resolve, reject) => {
setTimeout(resolve, 1000);
}).then(() => {
console.log('成功時');
}).catch(e => {
console.log('エラー時');
}).finally(() => {
console.log('成功してもエラーでも実行される');
});
オブジェクトでもスプレッド構文
// オブジェクトを複製したり、別データを作るのに便利
const data = {
width: 100,
height: 200,
};
const house = {
...data,
price: 4000,
};
console.log(house); // => { width: 100, height: 200, price: 4000 }
ES2017
padStartは地味に便利です。
String.prototype.padStart
// 日付処理に便利
'5'.padStart(2); // => ' 5'
'5'.padStart(2, '0'); // => '05'
Object.values, Object.entries
// for文でオブジェクトデータを取り出すのに便利
const data = {
japan : 'east',
us : 'west',
}
for(const val of Object.values(data)){
console.log(val);
}
for(const [key, val] of Object.entries(data)){
console.log(key, val);
}
async / await
// 非同期処理を同期っぽく書ける構文
const timer = (time) => {
return new Promise((resolve) => {
setTimeout(resolve, msec)}
);
};
(async () => {
await sleep(1000);
console.log('1秒立ちました.')
})();
ES2016
includesは直感的で便利です。indexOfの利用頻度は下がるでしょう。
Array.prototype.includes
// 配列内にデータがあるか存在確認
const pets = ['cat', 'dog', 'bat'];
pets.includes('cat'); // => true
pets.includes('mouse'); // => false
ES2015(ES6)
ES2015は名称の過渡期で、始めはES6(ECMAScript6)とも呼ばれていました。そのため過去の情報ではES6として説明されているサイトもよくあります。
let
// ブラケット内スコープで使えて再代入可能な変数let
if(a == 'a'){
let x = 1;
x = 2;
console.log(x); // 2が出力される
}
console.log(x); // スコープ外なのでundefined
const
// ブラケット内スコープで使えて再代入できない変数const
if(a == 'a'){
const x = 1;
x = 2; // 代入禁止エラーとなる
}
console.log(x); // スコープ外なのでundefined
アロー関数
// 関数の書き方がスッキリするアロー関数
const add = (a, b)=>{
return a + b;
};
add(1, 2); // 3が戻ってくる
// こういう書き方もできる(読みにくいのでおすすめしない。)
const log = (msg) => console.log(msg);
const alert = msg => alert(msg);
テンプレートリテラル
// バッククォートで囲むことで変数を代入したり、複数行に渡って文字列定義をすることができます。
const error = '404 not found';
const msg = `
以下のエラーが発生しました。
${error}
しばらくしてから再度アクセスしてください。
`;
alert(msg);
スプレッド構文
// ...と書くこで、配列が展開された状態で使うことができる。
const array = [1, 2, 3];
const x = [...array, 4, 5, 6]; // [1, 2, 3, 4, 5, 6]
const y = [-2, -1, 0, ...array]; // [-2, -1, 0, 1, 2, 3]
Promise
// 非同期処理をすっきり記述できる構文
const timer = new Promise((resolve, reject)=>{
setTimeout(()=>{
resolve('finished.');
}, 1000);
});
timer.then((msg)=>{
console.log(msg) // => 1秒後に'finished.'
});
分割代入
// オブジェクトから必要な変数だけ抽出することができる
const data = {
width: 100,
height: 200,
kind: 'dog',
color: 'black',
};
const {width, height} = data;
importとexportによるモジュール構文
// Sample.js
// エクスポート定義する方法
export default (msg)=>{
console.log(`デフォルトメッセージ:${msg}`);
};
export const name1 = (msg)=>{
console.log(`name1メッセージ:${msg}`);
};
export const name2 = (msg)=>{
console.log(`name2メッセージ:${msg}`);
};
// インポートする方法
import Sample, { name1, name2 } from './Sample';
Sample('sample'); // => デフォルトメッセージ:sample
name1('111'); // => name1メッセージ:111
name2('222'); // => name2メッセージ:222
trim
// 文字の両端の空白を取り除く
' abc '.trim(); // => 'abc'
以上になります。 ES2015が1番多くの構文が追加されましたが、細かいけど便利な記法が他のバージョンでも追加されたことがわかると思います。
Webpack & Babelを使うことが一般的となってきたので、ブラウザバーションを気にせず最新の記法を使える時代となったので、覚えておくといいですね。