JavaScriptのクラス(Class)は、オブジェクト指向プログラミングを扱う上で重要な構文です。
前回は、オブジェクト指向の基となるクラスの定義方法やインスタンス化について解説しました。

今回は、インスタンスメソッドとアクセッサプロパティを使用したクラスの活用方法を見ていきましょう。

インスタンスメソッド

クラスの動作を定義するためのメソッドを「インスタンスメソッド」と呼びます。また、「プロトタイプメソッド」とも呼ばれています。

インスタンスメソッドは、クラスのインスタンスに対して自由に定義することができるメソッドで、名前の通り、インスタンスを通じて呼び出します。

クラスの中に任意のメソッドを作成し、コンストラクタメソッドと同様にthisを使います。

//クラスを定義
class Classname {
  constructor(x, y) {
    this.x = x;
    this.y = y;
  }

  //インスタンスメソッドを定義
  method(z) {
    this.z = z;
  }
}

//インスタンス化
const instance = new Classname('x', 'y');

//インスタンスメソッドを実行
instance.method('z');
console.log(instance.x, instance.y, instance.z) //"x", "y", "z"

インスタンスメソッドを使うと、各インスタンスが持つ動きを決められることが分かります。

インスタンスメソッドは、「プロパティ名:値」のようにオブジェクトの書き方でメソッドを定義することができないため、注意が必要です。

もう少し具体的な例を見てみましょう。「HealthCheck」というクラスを使用した例です。

class HealthCheck {
  constructor(place, date) {
    this.place = place;
    this.date = date;
  }
  register(person) {
    this.person = person;
  }
}

const userInfo = new HealthCheck('ABC病院', '9月13日');
userInfo.register('山田花子');

console.log(userInfo.place, userInfo.date, userInfo.person); 
//"ABC病院", "9月13日", "山田花子"

健康診断を受診するために、「register」というインスタンスメソッドを作成しています。
その中には、受診する人を登録するためのプロパティが用意されています。

このように、インスタンスメソッドは、クラスの各インスタンスの間で共有できることが特徴です。

プライベートとカプセル化

外部からアクセスして欲しくないメソッドやプロパティのことを「プライベートメソッド/プロパティ」と呼びます。

他のオブジェクト指向言語には、外部からアクセスできないようにするためのプライベートという概念がありますが、現時点ではJavaScriptにはそのような概念がありません。

そのため、JavaScriptではクラスの外部から読み書きされたくないメソッドやプロパティの前に、「_」を使用し、プライベートを表現しています。

class Classname {
  constructor(x, y) {
    this._x = x;
    this._y = y;
  }

  _method() {

  }
}

クラスの外部からアクセスする必要のない情報(メソッドやプロパティ)を隠すことを「カプセル化」と呼びます。

しかし、実際には外部からのアクセスはできてしまうため、プライベートを表現する慣習であるということを覚えておくと良いでしょう。

class Classname {
  constructor(x, y) {
    this.x = x;
    this._y = y;
  }

  _method(z) {
    this._z = z;
  }
}

const instance = new Classname('パブリック' , 'プライベート');
instance._method('プライベート');
console.log(instance.x, instance._y, instance._z); 
//"パブリック", "プライベート", "プライベート"

「WeakSet」という手法を使うことで、外部からアクセスできなくなるプライベートを実現することができますが、この解説はまた別の記事で取り上げます。

アクセッサプロパティ

JavaScriptには、「getter」と「setter」というメソッドが用意されており、これらを「アクセッサプロパティと呼びます。アクセッサプロパティは、メソッド名の前に「get」または「set」を記述して使用します。

それぞれ役割を見ていきましょう。

getter

「getter」は、オブジェクトの持つプロパティを参照する場合に使われます。

getterを使う際には、引数は必要ありませんが、必ず値を返すことが必要です。

class Classname {

  get method() {
    return 値;
  }
}
const instance = new Classname();
instance.method;

例えば、担任の先生の名字のみを返すgetterメソッドを定義するとこのようになります。

class Teacher {
  constructor(props) {
    this.name = props.name;
  }

//プロパティの値を返すgetter
  get lastName() {
    return this.name.split(' ')[0];
  }
}

const myTeacher = new Teacher({
  name: '山田 花子'
})

console.log(myTeacher.lastName); //"山田"

getter

getterを通じてプロパティの値が返されます。
ここでは「this.name.split(‘  ‘)」によって、名前のスペースを基準に名字と名前を2つの要素に分けています。
その後、「[0]」のように、1つ目の要素を返すことで名字を得ることが可能です。

setter

「setter」は、オブジェクトの持つプロパティを代入する場合に使われます。

setterを使う際は、引数を記述します。プロパティに代入された値がこの引数に入ります。getterのように値を返す必要はありません。

class Classname {

  set method(引数) {
    処理;
  }
}
const instance = new Classname();
instance.method = 値;

担任の先生が変わったとして、名前をアップデートしてみましょう。

class Teacher {
  constructor(props) {
    this.name = props.name;
  }

  //プロパティの値を代入するsetter
  set newTeacher(newName) {
    this.name = newName;
  }
  //プロパティの値を返すgetter
  get newTeacher() {
    return this.name;
  }
}

const myTeacher = new Teacher({
  name: '山田 花子'
})

myTeacher.newTeacher = '田中 太郎'; //値がsetterの引数に渡る
console.log(myTeacher.newTeacher); //"田中 太郎"

setter

「myTeacher.newTeacher = ‘田中 太郎’」のように、ここで新しく加えられた値がsetterの引数に渡っています。

setterはプロパティの参照には使用できないため、getterを使ってアップデートされたプロパティを参照しています。
getterの記述がない場合にプロパティ参照しようとすると、undefinedとなるため、注意してください。

まとめ

今回は、クラス(Class)のインスタンスメソッドやアクセッサプロパティについて解説してきました。

クラスをインスタンス化するだけではアクションを起こすことができませんが、インスタンスメソッドを活用することで、各インスタンスの動作を定義することができます。

また、アクセッサプロパティを用いるとプロパティの参照や代入を効率的に行うことも可能です。

オブジェクトをより便利に操作することができるため、ぜひ活用してみてください。

JavaScript関連記事