ES2016 / ES2017の最新動向を追ってみた

  • 98
    いいね
  • 2
    コメント

はじめに

最近ECMAScriptの仕様を追いかけていなかったので勉強してみることにしました。
最新というよりは自分の知らない記法や、見たことあるけど意味は分からないというようなものをまとめてみたというかんじです。
仕様のソースは以下を参考にさせていただきました。

TC39のFinished Proposals

Stage

ECMAScriptはTC39という仕様策定委員会の監修のもと、以下の5つのステップを通過した上でリリースしていて、その段階をStageと呼称しています。

Stage 概要
0 Strawman - [アイデア]
1 Proposal - [提案]
2 Draft - [ドラフト]
3 Candidate - [実装候補]
4 Finished - [実装予定]

今回はES2016で実装された2つの仕様と、ES2017以降で実装されるであろうStage 4の仕様の紹介をしていきたいと思います。

Array.prototype.includes()

配列内に求めている値が入っているかをtrue or falseで返しています。
今までの値チェックの方法はindexOf()とか使って値が入っているかどうかを確認していましたが、正直-1を返すとかが若干ややこしかったので返ってくる値がboolean型なのは可読性がぐっと上がるだろうなと感じたので、今後はこれを使っていこうと思いました。

const arr = ['hoge', 'fuga', 'piyo'];

console.log(arr.includes('hoge')); // true
console.log(arr.includes('hogera')); // false
仕様 リリース日
ES2016~ 2016/06/17

参照元: https://github.com/tc39/Array.prototype.includes/

Exponentiation Operator

Exponentiation(冪乗・累乗)が簡単に使えるようになった模様。
この記法はPythonやRubyではよく使われるそうですが、果たしてJSではどのように使われるのでしょうか…。
ブラウザ上で使用する電卓とかですかね?笑

※この**という記法はべき乗演算子というそうです。

console.log(2 ** 2); // 4
console.log(2 ** 8); // 256
console.log(2 ** 10); // 1024
仕様 リリース日
ES2016~ 2016/06/17

参照元: https://github.com/rwaldron/exponentiation-operator

Object.values() & Object.entries()

  • Object.values()はオブジェクトのvalueを配列にして返すメソッド。
  • Object.entries()はオブジェクトを[key, value]という形で多次元配列にして返すメソッド。

Object.keys()というkeyを配列にして返すメソッドは存在していましたが、valueを配列にして返すメソッドがありませんでしたが、ES2017以降はそれが使用可能になります。


const obj = {
  name: 'yuyake0084',
  bloodType: 'B'
};

Object.keys(obj); // ["name", "bloodType"] <= ES2015から実装可能
Object.values(obj); // ["yuyake0084", "B"]
Object.entries(obj); // [["name", "yuyake0084"], ["bloodType","B"]]
仕様 リリース日
ES2017~ 未定

参照元: https://github.com/tc39/proposal-object-values-entries

String padding

String.prototype.padStart()

指定した文字数になるように、先頭に指定した文字列を差し込む事ができるメソッド。
使い方としては、第一引数に指定文字数を入れ、第二引数では差し込む文字列を入れます。
差し込む文字数ともとの文字数の和が、指定した文字数に満たない場合は、
その数に到達するまで差し込む文字列を繰り返し差し込みます。
逆に、指定した文字数より、差し込む文字数ともとの文字数の和が多くなる場合は、
指定数からもとも文字数を引いた数だけ第二引数を差し込み、以降の文字列をカットして文字列の結合をします。

const str = 'hoge';

console.log(str.padStart(10));         //       hoge    全部で10文字になるよう デフォルトの空文字''を繰り返す
console.log(str.padStart(10, 'fuga')); // fugafuhoge    全部で10文字になるよう fugaを繰り返す
console.log(str.padStart(5, 'piyo'));  // phoge         全部で 5文字になるよう piyoをカット

String.prototype.padEnd()

padStart()とは違い、末尾に文字列を結合します。

const str = 'hoge';

console.log(str.padEnd(10)); // hoge      
console.log(str.padEnd(10, 'fuga')); // hogefugafu
console.log(str.padEnd(5, 'piyo')); // hogep

※2017年1月19日時点ではChromeでの動作は確認できませんでしたが、FireFoxでは動作確認できました。

仕様 リリース日
ES2017~ 未定

参照元: https://github.com/tc39/proposal-string-pad-start-end

Object.getOwnPropertyDescriptors()

………………………長っ!
なんて長いメソッド名でしょう。
これは覚えるのに少々時間がかかりそうなイメージですが、メソッド名の意味を紐解いていくと「ああ、なるほどね」となるはずです。
Descriptorsは直訳すると記述子といってデータやファイルの性質という意味を持っています。つまり、『オブジェクトのプロパティのデータの性質を取得するよ』というメソッドと解釈しています。

じゃあどんなオブジェクトが返ってくるかを確認してみましょう!

const obj = {
  name: 'yuyake0084',
  get hello() {
    return `Hello my name is ${this.name}`;
  }
};
const descriptor = Object.getOwnPropertyDescriptors(obj);

console.log(descriptor);

// descriptor = {
//   hello: {
//     configurable: true,
//     enumerable: true,
//     get: hello(),
//     set: undefined
//   },
//   name: {
//     configurable: true,
//     enumerable: true,
//     value: "yuyake0084",
//     writable: true
//   }
// }

なるほど、たしかにnameの情報がオブジェクトとして返ってきてるみたいです。
それぞれどういう意味なのか分からなかったのでググって表にしておきます。

プロパティ 意味
configurable Descriptorを編集する事が可能かどうか
enumerable valueをfor...inで列挙可能かどうか
get getterの関数を返します
set setterの関数を返し、setがなければundefindを返します
value keyに対してのvalue
writable 値の書き換えが可能かどうか

以上6つのフィールドを持っていて、keyによって返ってくるオブジェクトの内容が変わってくるようです。
もともとES5にあったメソッドだったらしいのですが、ES2017から書き方がシンプルになって実装されるようです。

// ES5

const descriptor = Object.getOwnPropertyDescriptors(obj, 'hello');
const descriptor = Object.getOwnPropertyDescriptors(obj, 'name');
仕様 リリース日
ES2017~ 未定

参照元: https://github.com/tc39/proposal-object-getownpropertydescriptors

Trailing commas in function parameter lists and calls

引数を改行で書いた時の最後のカンマを許容するようです。
地味に嬉しい仕様ですね。

function hoge(
  name,
  bloodType, // <= これ
) {
  return `My name is ${name}! Blood Type is ${bloodType} type.`;
}

hoge(
  'yuyake0084',
  'B',
);
仕様 リリース日
ES2017~ 未定

参照元: https://github.com/tc39/proposal-trailing-function-commas

Async Functions

別名、Async/Awaitと呼ばれているもので、非同期処理を同期的に書く事ができる文法です。
以下はPromiseがES2015に実装された非同期処理の書き方の一例です。

// Promise

function theWorld(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`${n}秒経過`);
      resolve(n + 1);
    }, 1000);
  });
}

theWorld(1)
  .then(theWorld)
  .then(theWorld)
  .then(() => {
    setTimeout(() => {
      console.log('時は動き出す');
    }, 1000);
  });

theWorldという関数が実行され、3秒経過した後で『時は動き出す』というログを吐くというだけの処理ですね。
ではこれをAsync functionsで書くと以下のようになります。

// Async functions

function theWorld(n) {
  return new Promise((resolve, reject) => {
    setTimeout(() => {
      console.log(`${n}秒経過`);
      resolve(n + 1);
    }, 1000);
  });
}

async function StarPlatinumTheWorld(init) {
  let n;

   n = await theWorld(init);
   n = await theWorld(n);
   n = await theWorld(n);
   console.log('時は動き出す');
};

 StarPlatinumTheWorld(1);

なるほど、たしかに同期的っぽく書けますね。
Promiseも素敵ですけどAsync/Awaitの方が可読性が高いような気がします。

仕様 リリース日
ES2017~ 未定

参照元: https://github.com/tc39/ecmascript-asyncawait

まとめ

斬新かつ実用性があるメソッドがたくさん出てきましたね!
ただ、完全に理解しきれていないのでこれからたくさん使っていって自身に落とし込んでいこうかなと思います。(特にAsync/Await。。。)
ではでは〜

参考にさせていただいた記事