JavaScriptでのfunctionを用いたクラス定義

JavaScriptでのfunctionを用いたクラス定義

JavaScriptでのfunctionを用いたクラス定義

JavaScriptでは、class構文を使わずに、functionを用いてクラスを定義することができます。 これは古いJavaScriptコードや、クラス構文が導入される以前(ES6以前)のコードで特によく見られます。このページでは、 その仕組みを詳しく解説し、数学的な概念との対応や例を交えて紹介します。

コンストラクタ関数とは

JavaScriptでは、functionを用いてクラスのようなオブジェクトを生成する方法があります。 これは「コンストラクタ関数」と呼ばれます。コンストラクタ関数は、新しいオブジェクトを初期化する役割を持ちます。 new演算子を使用して、この関数を呼び出すことで、オブジェクトが生成されます。

function Person(name, age) {
    this.name = name;
    this.age = age;
}

const person1 = new Person("Taro", 25);
console.log(person1.name); // "Taro"
console.log(person1.age);  // 25

上記のコードでは、Personという名前のコンストラクタ関数を定義しています。 newを用いることで、この関数は新しいオブジェクトを生成し、thisにそのオブジェクトをバインドします。

プロトタイプメソッドの定義

コンストラクタ関数を用いた場合、インスタンスメソッドはプロトタイプを通じて定義するのが一般的です。 これは、各インスタンスで同じメソッドを共有するための仕組みです。

Person.prototype.greet = function() {
    console.log("Hello, my name is " + this.name);
};

const person2 = new Person("Hanako", 30);
person2.greet(); // "Hello, my name is Hanako"

この方法では、メソッドはオブジェクトごとに複製されず、メモリ効率が良くなります。 prototypeプロパティを活用することで、効率的なメソッド定義が可能になります。

継承の実装

コンストラクタ関数を使ったクラス定義では、プロトタイプチェーンを活用して継承を実現します。 例えば、Personクラスを継承してStudentクラスを作成する場合、以下のように実装します。

function Student(name, age, grade) {
    Person.call(this, name, age); // 親クラスのコンストラクタを呼び出す
    this.grade = grade;
}

Student.prototype = Object.create(Person.prototype); // プロトタイプを継承
Student.prototype.constructor = Student; // コンストラクタを修正

Student.prototype.study = function() {
    console.log(this.name + " is studying in grade " + this.grade);
};

const student1 = new Student("Ken", 18, "12th");
student1.greet(); // "Hello, my name is Ken"
student1.study(); // "Ken is studying in grade 12th"

上記のコードでは、callを使って親クラスのコンストラクタを呼び出し、 Object.createでプロトタイプチェーンを設定しています。

数学的な対応関係

この継承の仕組みを数学的に表現すると、Personクラスが関数 \\(f(x)\\) に対応し、 Studentクラスが \\(g(x)\\) に対応すると考えることができます。 \\[ g(x) = f(x) + h(x) \\] ここで、\\(h(x)\\) は新しいプロパティやメソッドを表します。 プロトタイプチェーンは、\\(g(x)\\) が \\(f(x)\\) の動作を継承していることを示しています。

実践的な例

ここでは、functionを用いたクラス定義を実際のシナリオでどのように活用するかを示します。

例: 図形の面積を計算する

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

Shape.prototype.getName = function() {
    return this.name;
};

function Circle(radius) {
    Shape.call(this, "Circle");
    this.radius = radius;
}

Circle.prototype = Object.create(Shape.prototype);
Circle.prototype.constructor = Circle;

Circle.prototype.getArea = function() {
    return Math.PI * Math.pow(this.radius, 2);
};

const circle1 = new Circle(5);
console.log(circle1.getName()); // "Circle"
console.log(circle1.getArea()); // 78.53981633974483

この例では、Shapeを基底クラスとして、Circleクラスがそれを継承しています。 getAreaメソッドは、円の面積を計算します。

コメントを残す

メールアドレスが公開されることはありません。 が付いている欄は必須項目です