ECMAScript 2015を理解する-クラス定義

参考:
いまからはじめるECMAScript 6
どうやってECMAScript 6を学び始めるか
ES6(ECMAScript6)でのJavaScriptの書き方 | 姫路のホームページ製作屋WILDWEST-SERVICE
ECMAScript 6 compatibility table
Rubyist Magazine - 2015 年の JavaScript と babel の話
ECMAScript Language Specification ECMA-262 6th Edition – DRAFT

クラス定義

uraway.hatenablog.com
前回インスタンスについての記事で、JavaScriptにはclass構文はないと書きましたが、新仕様ECMAScript 2015において、class構文が追加されました。


JavaScriptにおいては、コンストラクタ関数を定義し、prototypeに対してメソッドを定義することで、クラスライクなものをつくります。

var Dog = function(x, y, cry) {
  this.x = x;
  this.y = y;
  this.cry = cry
}
Character.prototype.bark = function() {
  console.log(this.cry);
};

しかし、これの糖衣構文として、classが追加されました。

class Dog {
  constructor(x, y, age) {
    this.x = x;
    this.y = y;
    this.age = age;
  }
  howOld(dog) {
    console.log(this.age)
  }
}

クラスは、他のクラスを継承することで基本機能を維持しながら新しい機能を付加することができます。

class Dog {
  constructor(x, y, age) {
    this.x = x;
    this.y = y;
    this.age = age;
  }
  howOld(dog) {
    console.log(this.age)
  }
}
class Cat extends Dog {} //Catクラスを継承
// Character クラス
class Character {
  constructor(x, y) {
    this.x = x;
    this.y = y;
    this.health_ = 100;
  }
  attack(character) {
    character.health_ -= 10;
  }
}

// 当然継承もある。
// Monster クラスに継承
class Monster extends Character {
  constructor(x, y, name) {
    super(x, y);
    this.name = name;
  }

  // メソッド書くときはこう書く
  attack(character) {
    // 親クラスのメソッド呼ぶときはこう
    super.attack(character);
    // super(character) でも同じ意味になる
  }

  // get prefix を付けられる
  get isAlive() { return this.health_ > 0; }
  get health() { return this.health_; }
  // set prefix を付けられる
  set health(value) {
    if (value < 0) throw new Error('Health must be non-negative.');
    this.health_ = value;
  }
}
var myMonster = new Monster(5,1, 'arrrg');
var yourMonster = new Monster(5,1, 'nyan');
// get prefix をつけるとプロパティアクセスのようにメソッドを扱える
console.log(myMonster.health); // 100
console.log(myMonster.isAlive); // true
// set prefix でも同様。
myMonster.health = 1;
console.log(myMonster.health); // 1
console.log(myMonster.isAlive); // true

myMonster.attack(yourMonster);
console.log(yourMonster.health); //90

Rubyist Magazine - 2015 年の JavaScript と babel の話