速習ECMAScript6 良いです

速習ECMAScript6: 次世代の標準JavaScriptを今すぐマスター!

速習ECMAScript6: 次世代の標準JavaScriptを今すぐマスター!

1年前に購入して放置してしまっていました。
 
実例と使い所を整理して記載してくれています。
blogやQiitaなどにもES6/2015の記事はありますが、こちらは1冊にまとまってまとめて読めるのが良いです。
とりあえずこれ一冊読んでおけば良いという印象。
ある程度知識はあるので、移動時間の1時間ほどで読めました。
お値段も 250円とお安いです。

 
以下、個人的に気になったことなど(主な内容などには触れていないです)。

const を誤解していた

基本constで変更するものはletみたいなノリで書いていましたが
constは、正しくは「再代入できない」であって、「変更できない」ではないです。
なので以下のようなことが可能。

const data = [1, 2, 3];
cata[0] = 10;
console.log(data);

// Array [
//   10,
//   2,
//   3
// ]

2、8進数変換

Number関数で2、8進数変換が可能。
Number#parseIntは、16進数のみの認識なので、Number関数で統一するのが望ましい。

let num = 10;
// 10進数 => 8進数変換
console.log(num.toString(8));
// "12"

// 10進数 => 2進数変換
console.log(num.toString(2));
// "1010"

// 8進数 => 10進数変換
console.log(Number('0o12'));
// 10

// 2進数 => 10進数変換
console.log(Number('0b1010'));
// 10

テンプレート文字列の関数引き渡し

「関数名テンプレート文字列」の形式で関数に引き渡せる。

function _e(str) {
  if (!str) { return ''; }
  // 変換表ESCに従って、文字列を置き換え
  return str.replace(/[<>&"']/g, function(submatch) {
    const ESC = {
      '<': '&lt;',
      '>': '&gt;',
      '&': '&amp;',
      '"': '&quot;',
      "'": '&#39;'
    };
    return ESC[submatch];
  });
}

// 分解されたtemplatesとvaluesを順に連結(valuesは_e関数でエスケープ)
function escape(templates, ...values) {
  let result = '';
  for (let i = 0; i < templates.length; i++) {
    result += templates[i] + _e(values[i]);
  }
  return result;
}

// テンプレート文字列をエスケープ処理
let name = '<TOM & Jerry>';
console.log(escape`こんにちは、${name}さん!`);
// "こんにちは、&lt;TOM &amp; Jerry&gt;さん!"

Symbol

Symbol の使い所が分かっていなかったのですが、以下のような使い道があるようです。

定数の値

従来の定数。

var JAVASCRIPT = 0;
var RUBY = 1;

これだと、比較時に値である数値が利用できてしまう。
他の似たような値を持つ定数が出てきたときにわかりにくい。  
そこでSymbolを使うと、以下のように定義することができる。

const JAVASCRIPT = Symobl();
const RUBY = Symbol();

 
従来の定数の場合は値に意味があるので、正直この使い方は微妙な気がします。

非公開なプロパティ

これはなるほどと思いました。

// SECRETプロパティの名前でシンボルで準備
const SECRET = Symbol();
class MyClazz {
  constructor(secret) {
    this.data1 = 1;
    this.data2 = 2;
    // SECRETプロパティに値を設定
    this[SECRET] = secret;
  }

  // SECRETプロパティを利用したメソッド
  checkSecret(secret) {
    return this[SECRET] === secret;
  }
}

let c = new MyClazz(12345);
// メソッド経由ではSECRETプロパティにアクセスできる
console.log(c.checkSecret(12345));
// true

// SECRETプロパティへの直接アクセスは不可
console.log(c.secret);
// undefined

 
正確には非公開ではないです。

let idsym = Object.getOwnPropertySymbols(c)[0];
console.log(c[idsym]);
// 12345

for…of

あれ、これ認識してなかった。欲しかったやつやん。
プロパティ、prototype拡張を考慮しない for…in

let data = [1, 2, 4];
Array.prototype.hoge = function() {};
for (let d of data) {
  console.log(d);
}
// 1 2 4

Proxyオブジェクト

これは全然分かってなかった。
オブジェクトの標準的な操作を差し替えるためのオブジェクト。

let obj = { hoge: 'ほげ', foo: 'ふー' };
let proxy = new Proxy(obj, {
  get(target, prop) {
    return prop in target ? target[prop] : '?';
  }
});

console.log(proxy.hoge);
// ほげ
console.log(proxy.nothing);
// ?

構文

new Proxy(target, handler)

主なhandler methodは以下。
get, set, enumberate, iterate, deleteProperty

プロパティ名の動的生成

こんなことできたんだ。

let i = 0;
let data = {
  ['hoge' + ++i]: 15,
  ['hoge' + ++i]: 20,
  ['hoge' + ++i]: 25
};
console.log(data);
// Object {
//   "hoge1": 15,
//   "hoge2": 20,
//   "hoge3": 25
// }

組み込みオブジェクトの継承

extendsキーワードで継承可能。
独自の例外オブジェクトの実装に便利。

目次

Part1は省略していますが、ざっとこんな感じです。
PromiseやProxy、モジュールの説明もわかりやすく書かれています。

Part2:基本構文
 ブロックスコープを有効にする - let命令
 定数を宣言する - const命令
 整数リテラルの表現力を改善する - 2進数/8進数リテラル
 文字列リテラルへの変数/改行の埋め込みを可能にする - テンプレート文字列
  テンプレート文字列をアプリ仕様に加工する - タグ付きテンプレート文字列
 新たなデータ型Symbolとは?
  シンボルの用法
   (1)定数の値として利用する
   (2)非公開なプロパティを定義する
 配列/オブジェクトから個々の要素を抽出する - 分割代入
  分割代入の使い方
   (1)関数(メソッド)から複数の値を返したい
   (2)変数の値を入れ替える
   (3)名前付き引数を指定する
   (4)正規表現でマッチした部分文字列を抽出する
 配列を個々の変数に展開する - 展開演算子
 配列など反復可能なオブジェクトを列挙する - for...of命令

Part3:関数
 引数のデフォルト値を宣言する
  補足:必須パラメーターの表現
 可変長引数を利用する
 関数リテラルをシンプルに記述する - アロー関数
  アロー関数はthisを固定する(レキシカルなthis)
  注意:オブジェクトリテラルを返す時

Part4:組み込みオブジェクト
 非同期処理を簡便に処理する - Promiseオブジェクト
  非同期処理を連結する
  複数の非同期処理を並行して実行する
 オブジェクトの挙動をカスタマイズする - Proxyオブジェクト
 コレクション関連のオブジェクトを標準で提供 - Map/Setなど
  キー/値のセットを管理するマップ
  一意な値の集合を管理するセット
 Unicode対応の改善
  for...of構文でもサロゲートペアを認識
  Unicodeエスケープシーケンスが拡張
  サロゲートペアからコードポイントを取得/設定も可能に
  RegExpオブジェクトにuフラグが追加
 String/Array/Math/Objectなど組み込みオブジェクトのメソッドも拡充
  Stringオブジェクト
  Arrayオブジェクト
  Mathオブジェクト
  Numberオブジェクト
  RegExpオブジェクト
  Objectオブジェクト

Part5:オブジェクト指向構文
 オブジェクトリテラルをよりシンプルに表現する
  変数を同名のプロパティに設定する
  メソッドを定義する
  プロパティ名を動的に生成できる
 クラスを定義する - class命令
  匿名クラス(リテラル表現)も利用できる
  静的メソッドを定義する - static修飾子
  getter/setterも利用できる
  既存のクラスを継承する - extendsキーワード
 列挙可能なオブジェクトを定義する - イテレーター
  イテレーターを実装したクラスの準備
 列挙可能なオブジェクトをより簡単に実装する - ジェネレーター
  カウントダウンするジェネレーター
 アプリを機能単位にまとめる - モジュール
  モジュールの内容をまるごとインポートする
  デフォルトのエクスポートを宣言する
  補足:ブラウザー環境で動作するには?