Edited at
LIGincDay 4

ES5とTypeScriptでクラスの実装を比べてみる

More than 3 years have passed since last update.

これまでのJavaScriptではclass文がなく、代わりに関数を使用してclassを実装していきます。このあたりが、class文に慣れた方がJavaScriptに戸惑う原因にもなっていると思います。


classを実装してみる

ここでは以下の流れのPersonクラスを作ります。


  1. Personクラスを定義

  2. nameプロパティをセット

  3. say、walkメソッドを実装

  4. インスタンスを生成

  5. メソッドを実行


JavaScriptで実装してみる

今まで通りJavaScriptでPersonというクラスを実装してみたいと思います。


var Person = function(name){
this.name = name || "dammy";
}

Person.prototype.say = function() {
console.log("Hello, I'm " + this.name);
};

Person.prototype.walk = function() {
console.log(this.name + " is walking");
};

var p = new Person("Yuta");

// Hello, I'm Yuta
p.say();

// Yuta is walking
p.walk();


TypeScriptで実装してみる

今度はTypeScriptでclassを実装してみたいと思います。


class Person {
constructor(
private name:string = "dammy"
) {}

public say():void {
console.log("Hello, I'm " + this.name);
}

public walk():void {
console.log(this.name + " is walking");
}
}

var p = new Person("Yuta");

// Hello, I'm Yuta
p.say();

// Yuta is walking
p.walk();

1行目:classを定義しています。

2行目:クラスからインスタンスを作成した際に、自動的に実行されるメソッドで、主に初期化などを行います。引数に初期値を設定することができます。

privateやpublicはアクセス修飾子と呼ばれています。privateはクラス内のアクセスのみ許可しています。publicはクラス外のアクセスを許可します。

一般的にはプロパティはprivate、メソッドをpublicにするケースが多いと思います。


classを継承してみる

今度はPersonクラスを継承してPhotographerクラスを実装したいと思います。


  1. Photographerクラスを定義

  2. PhotographerクラスがPersonクラスを継承

  3. name,cameraプロパティをセット

  4. sayメソッドをオーバーライド

  5. release,hasCameraメソッドを定義

  6. インスタンスを生成

  7. メソッドを実行


JavaScriptで実装してみる

上と同じく従来通りのJavaScriptで記述します。


Personクラス


var Person = function(name){
this.name = name || "dammy";
}

Person.prototype.say = function() {
console.log("Hello, I'm " + this.name);
};

Person.prototype.walk = function() {
console.log(this.name + " is walking");
};


Photographerクラス


var Photographer = function(name,camera){
this.name = name || "dammy";
this.camera = camera || "";
}

// Personを継承
Photographer.prototype = Object.create(Person.prototype);

Photographer.prototype.say = function() {
console.log("Hello, I'm " + this.name + "! My job is photographer");
};

Photographer.prototype.release = function() {
console.log("take a picture");
};

Photographer.prototype.hasCamera = function() {
console.log(this.camera? true : false);
};

var photographer = new Photographer("Yuta","Nikon S2");

// Hello, I'm Yuta! My job is photographer
photographer.say();

// take a picture
photographer.release();

// true
photographer.hasCamera();

// Yuta is walking
photographer.walk();


TypeScriptで実装してみる


Personクラス


class Person {
constructor(
//private -> protected
protected name:string = "dammy"
) {}

public say():void {
console.log("Hello, I'm " + this.name);
}

public walk():void {
console.log(this.name + " is walking");
}
}

Personクラスを少し書き直しました。

constructorでのnameをprivateからprotectedに変更しています。

protectedにする事で継承先からアクセスする事ができます。


Photographerクラス


class Photographer extends Person {
constructor(
protected name:string = 'dammy',
private camera:string = ''
){
super();
}

public say():void {
console.log("Hello, I'm " + this.name + "! My job is photographer");
}

public release():void {
console.log("take a picture");
}

public hasCamera():void {
console.log(this.camera? true : false);
}
}

var photographer = new Photographer("Yuta","Nikon S2");

// Hello, I'm Yuta! My job is photographer
photographer.say();

// take a picture
photographer.release();

// true
photographer.hasCamera();

// Yuta is walking
photographer.walk();

継承の見通しが良くなりました。クラスは宣言時にPersonを継承していることがわかります。

constructor内でsuper()を呼ぶことで、PhotographerクラスもPersonクラスで定義されているメソッドを呼ぶことがで、行の最後でphotographer.work()を確認することができます。


まとめ

今回はクラスについてまとめました。TypeScriptも選択肢のひとつに上がるようになるといいなと思ってます!