ES2015 (ES6)についてのまとめ

  • 440
    いいね
  • 0
    コメント
この記事は最終更新日から1年以上が経過しています。

ECMAScriptとは

  • ECMAScriptはJavaScriptの中核仕様を抜き出して標準化したもの
  • 開発当初のJavascriptは、ブラウザによる独自の拡張が多く、互換性が低かったため、Ecma Internationalが中心となりECMAScriptが開発された

ES2015 (ES6)とは

先日策定された、ECMASCriptの6th Editionのことであり、当初はES6と呼ばれているが、正式名称をECMASCript2015(ES2015と呼ばれる)とし、今後は年単位のリリースを予定しているとのこと
[公式サイト]http://www.ecma-international.org/ecma-262/6.0/index.html

ES2015で可能となる新たなシンタックス

  • letconstキーワードによる変数宣言
  • class構文
  • 関数の引数のデフォルトパラメータ(Default Parameters)
  • アロー関数(Arrow Functions)
  • 分割代入(Destructing Assignment)
  • 配列展開(Array Spread)
  • 関数の可変長引数(Rest Parameters)
  • 関数のデフォルト引数
  • テンプレート文字列(Template Strings)
  • importとexportによるモジュール構文(Module)

let constによる変数宣言

ES5までは関数スコープのみしか存在しなかったため、varによる変数宣言に対して、スコープを利用するためには、無名関数を用いてスコープの作成をしていたが、
ES2015ではブラケット{}によるブロックスコープが可能となり、ブラケット内でletconstにより定義された変数はそのブラケットのスコープ内のみで生きることができる。
constは定数を宣言したい時に用いられ、constで宣言された変数は、宣言時を除いて値の代入が不可能である。再代入を行おうとすると、例外が発生し、プログラムがストップするため、プログラムレベルで値の不変性が保証される。

let foo = [1, 2, 3];
{
  let foo = [4, 5, 6];
  console.log(foo);
  // => 4, 5, 6
}
console.log(foo);
// => 1, 2, 3
{
  const PI = 3.14;
  const circleArea = function (radius) {
    return radius * radius * PI;
  };
  console.log(circleArea(3));
  // => 28.26
  // ここでPI = 3.1415;のような再代入を行おうとすると、例外が発生する
}
console.log(PI);
// => undefined

クラス構文

ES5までではprototype(あるオブジェクトの元になるオブジェクトという概念。RubyやJavaなどのクラスベースオブジェクト指向に対し、javascriptはプロトタイプベースオブジェクト指向と呼ばれる。)を利用することで、クラスのようなものを作成してきた。

function Human(name) {
  this.name = name;
}

Human.prototype.hello = function () {
  console.log('My name is ' + this.name);
};

Humanオブジェクトはhelloオブジェクトをprototypeとしてできており、Humanオブジェクトはhelloオブジェクトに対する暗黙の参照をもっているため、helloというプロパティでhelloオブジェクトを呼び出すことができる

obj = new Human('Izmeal')
obj.hello
//=> 'My name is Izmeal' 

これを、class構文を用いると、

class Human {
  constructor(name) {
    this.name = name;
  }
  hello() {
    console.log('My name is ' + this.name);
  }
}
obj = new Human('Koyabu')
obj.hello
//=> 'My name is Koyabu'

class構文についてもう少しみてみる。

constructorメソッド

constructorメソッドは、クラスがnewされた時に実行されるメソッドであり、クラス内で共通して使われるプロパティの初期値の定義などを行う。1つのクラスに1つしか定義できない。先ほどの例ではnameの初期値を代入している。(Rubyでいうinitializeメソッド)

prototypeメソッド

先ほどのHumanクラスのhelloのように、クラスのインスタンスから呼び出せるメソッドをprototypeメソッドという。(Rubyでいうインスタンスメソッド)

staticメソッド

インスタンスを生成する必要なくクラス名.メソッド名の形で呼び出せるメソッド。(Rubyでいうクラスメソッド)

class Human {
  constructor(name) {
    this.name = name;
  }
  hello() {
    console.log('My name is ' + this.name);
  }
  static num_of_hands() {
    console.log(2)
  }
}

Human.num_of_hands()
//=> 2

クラスの継承

extends キーワードをクラス宣言、もしくはクラス式内に記述することで、他のクラスの子クラスを定義できる。

class Animal { 
  constructor(name) {
    this.name = name;
  }

  speak() {
    console.log(this.name + ' makes a noise.');
  }
}

class Dog extends Animal {
  speak() {
    console.log(this.name + ' barks.');
  }
}

子クラス内で、親クラスのconstructorはsuper()で呼び出せ、親クラスのメソッドは、super.メソッド名()で呼び出せる。

アロー関数による関数宣言

従来のfuncitonを使った関数宣言に加えて、=>を用いた関数宣言が可能
アロー関数による関数宣言の特徴としては、
* 常に匿名関数
* 引数が一つの場合は()が省略可能
* bodyが単一式の場合は、{}やreturnを省略できる

// 従来のfunctionを使った書き方
var plus = function(x, y) {
  return x + y;
};

// アロー関数
let plus = (x, y) => {
  return x + y;
};

// 単一式の場合はブラケットやreturnを省略できる
let plus = (x, y) => x + y;
  • thisは関数が定義されたスコープにおけるthisを引き継ぐ
    これに対し、functionによる関数定義では、それぞれの関数がそれ自身の thisの値を新たに定義していた。(コンストラクターでは新しいオブジェクト、 strict モードでの関数呼び出し時はundefined、関数が"オブジェクトのメソッド" として呼び出された場合はそのオブジェクト、など)

  • リテラルを返す場合には()で囲む必要がある。(そうでないと波括弧の中は文としてパーシングされてしまう。)

var func = () => ({ foo: 1 });

アロー関数はSafariは未対応なので要注意

分割代入

一度に複数の変数に、複数の値を代入できる。

var name = Izmeal;
var age  = 21;

var [name, age] = ['Koyabu', 20];

とできる

配列展開

関数の呼び出し、配列への代入、構造化代入に対して、...により、配列を展開して用いる事ができる

var array = [1, 2, 3]
function f(x, y, z) { }
f(...array);
//f(1, 2, 3)という引数での関数fの呼び出しと同義

[...array, 4, 5, 6]
//[1, 2, 3, 4, 5, 6]となる
var x
var y
var z
var variables = [x, y, z]
[a, b, ...variables] = [1, 2, 3, 4, 5];
// a = 1, b = 2, x = 3, y = 4, z = 5とした場合と同じ

可変長引数

function f(x, ...ys) {
    console.log(x, ys);
}
f(2, 3, 5);
//=> 2 [ 3, 5 ]

デフォルト引数

function multiply(a, b = 1) {
  return a*b;
}
multiply(5); // 5

のように引数の()括弧内で代入を行うことで、デフォルト値を設定できる

テンプレート文字列

``で文字列を囲むことで、文字列内での変数展開が${}で行え、改行もそのまま反映できる

var name = 'Koyabu'

var hello = `My name is
${name}`
console.log(hello)
//=>My name is 
//Koyabu