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
メソッドは、円の面積を計算します。