javascriptの今と昔のクラスの書き方(+α)

初投稿になります。よろしくお願いします。

Javascriptのクラスについて調べていると、今(ES6以降)と昔(ES5)で書き方が異なっていましたので今回まとめてみようと思い、記事にしました。
今回は異なったコードを中心に見てもらいたいので前提だけ書いて長文は省略します。

# 目次
・クラスについて(軽く)
・昔と今の書き方
・昔と今の継承の書き方(軽く)
・昔と今のクラスのメリット・デメリット
・なぜjavascriptでクラスを学ぶのか

## クラスについて(軽く)
「クラス」はオブジェクト指向で重要なプログラミング言語の機能の一つであり、
統一された機能を作るための一つの**設計図**のようなものです。

## 昔と今の書き方

ES5ではクラスというのは存在せずコンストラクタ関数で疑似的にクラスを定義していました。
ES6では他の言語と同じようにクラス構文が追加されましたのでそれぞれを説明していきます。

### ES5（プロトタイプベースのクラス）
ES5では、関数コンストラクタとプロトタイプチェーンを使ってクラスのような構造を作成します。プロパティはコンストラクタ内で定義し、メソッドはプロトタイプオブジェクトに追加します。
```javascript: legacy_class.js
// コンストラクタ関数
function Person(name, age) {
    this.name = name;
    this.age = age;
}

// プロトタイプメソッド
Person.prototype.greet = function() {
    console.log("Hello, my name is " + this.name);
};

// インスタンスの作成
let person1 = new Person("John", 30);
person1.greet(); // Hello, my name is John
```
そしてメソッドを定義する際はコンストラクタ関数の外にprototypeを定義してから書きます。

### ES6以降（クラス構文）
ES6では class 構文が導入され、よりオブジェクト指向言語に近い形でクラスを定義できます。コンストラクタ、メソッド、継承などが明確で読みやすい書き方になります。
```javascript: modan_class.js
// クラス宣言
class Person {
    constructor(name, age) {
        this.name = name;
        this.age = age;
    }

    // メソッド
    greet() {
        console.log(`Hello, my name is ${this.name}`);
    }
}

// インスタンスの作成
const person1 = new Person("John", 30);
person1.greet(); // Hello, my name is John

```
メソッドはクラス構文の中に入ります。

## 昔と今の継承の書き方(軽く)
もちろん、継承の書き方も異なります。ここでは継承の説明は割愛します。

### ES5（プロトタイプベースのクラス）の継承
```javascript: legacy_extend.js
function Employee(name, age, jobTitle) {
    Person.call(this, name, age);  // 親のコンストラクタを呼び出し
    this.jobTitle = jobTitle;
}

// プロトタイプ継承
Employee.prototype = Object.create(Person.prototype);
Employee.prototype.constructor = Employee;

Employee.prototype.work = function() {
    console.log(this.name + " is working as a " + this.jobTitle);
};

var employee1 = new Employee("Alice", 28, "Developer");
employee1.greet();  // Hello, my name is Alice
employee1.work();   // Alice is working as a Developer
```

### ES6以降（クラス構文）の継承
```javascript: modan_extend.js
class Employee extends Person {
    constructor(name, age, jobTitle) {
        super(name, age);  // 親クラスのコンストラクタを呼び出し
        this.jobTitle = jobTitle;
    }

    work() {
        console.log(`${this.name} is working as a ${this.jobTitle}`);
    }
}

const employee1 = new Employee("Alice", 28, "Developer");
employee1.greet();  // Hello, my name is Alice
employee1.work();   // Alice is working as a Developer
```

## 昔と今のクラスのメリット・デメリット
そしてメリットとデメリットがそれぞれあります。

### ES5（プロトタイプベースのクラス）のメリット

#### 柔軟性:
後からでもプロトタイプチェーンを通してメソッドを追加できるため、クラスやオブジェクトを柔軟に拡張できます。たとえば、特定の条件下でだけメソッドを追加したり、既存のクラスにメソッドを追加することが簡単にできます。

#### メモリ効率:
クラスや関数のインスタンスが大量に作成される場合、プロトタイプにメソッドを定義しておくことで、メモリ効率がよくなります。各インスタンスごとにメソッドを作成するのではなく、プロトタイプに1つだけ定義されたメソッドをすべてのインスタンスが共有するため、メモリの節約になります。

#### レガシー環境での互換性:
ES5以前の古いJavaScript環境でも動作するため、古いブラウザやシステムとの互換性を保ちながら開発ができるという利点があります。

### ES5（プロトタイプベースのクラス）のデメリット

##### コードの見通しが悪くなる:
メソッドがクラス定義の外に記述されるため、どのメソッドがクラスに属しているのかが一目で分かりにくくなります。クラス定義とメソッドが離れてしまうと、コードの保守性が低下します。

##### コードの一貫性の欠如:
クラス定義とプロトタイプメソッドが別々に定義されることで、コードの一貫性が失われやすくなります。特に大規模なプロジェクトでは、どこに何が書かれているのかを探すのが難しくなることがあります。

#### モダンな開発スタイルに適さない:
ES6以降のclass構文が推奨される中で、プロトタイプベースのメソッド追加は古いスタイルと見なされることがあります。モダンな開発ではクラス構文を使う方が一般的で、特に大規模プロジェクトでは好まれます。

### ES6以降（クラス構文）のメリット

#### 読みやすい・理解しやすい:
メソッドがクラス定義の中に直接書かれているため、構造が一目でわかりやすい。特に、他の開発者がコードを読む際に、すべてのメソッドがクラスにまとまっているため、把握しやすい。

#### 一貫性:
メソッドとコンストラクタが同じ場所にあり、コードが整理されている。クラスとその動作が明確に1か所に集約されるので、クラスの構造が一貫して見える。

#### 直感的でモダン:
ES6以降の class 構文は、他のオブジェクト指向言語（Java、Pythonなど）に似ており、クラスの中にメソッドを直接書くというスタイルは、オブジェクト指向プログラミングに慣れた開発者にとって直感的です。

#### IDEやエディタのサポート:
モダンなエディタやIDE（統合開発環境）では、クラス定義の中にメソッドを書くと、自動補完やコードナビゲーションが効率よく行えるようになります。メソッドがクラス定義と一緒に見つかるため、開発がスムーズに行えます。

### ES6以降（クラス構文）のデメリット

#### 柔軟性が低い:
クラスを後から拡張したり、新しいメソッドを動的に追加する場合、クラス定義の中にすべてを書いておくと後からメソッドを変更するのが難しくなることがあります。

#### 古いJavaScriptのコードベースでは非互換:
もし古いブラウザやJavaScriptエンジン（ES5以前）をサポートする必要がある場合、class 構文は使えないことがあります。モダンな環境では問題ありませんが、レガシー環境では互換性が低いことがあります。

## なぜjavascriptでクラスを学ぶのか
現在、様々なjavascriptのフレームワークがでてきて、便利になっており、クラスなどはあまり使わないところが多いと思いますが、学んでおくことでjavascriptの標準で備わっている機能を深くまで理解できたりMDNサイトを見たとき、理解がしやすくjavascriptの更に奥を知れると思います。