はじめに
JavaScriptでクラスやオブジェクトを扱う際、コンストラクタ、プロパティ、静的メソッドという用語に出会います。これらは似ているようで全く異なる役割を持っており、正しく理解することでより効果的なコードが書けるようになります。
この記事では、以下の内容を学べます。
- コンストラクタ、プロパティ、静的メソッドそれぞれの役割
- 3つの違いと使い分け方
- JavaScriptのクラスが持つ本質的な特徴
- 実践的なコード例による理解の深化
コンストラクタとは
コンストラクタの役割と定義
コンストラクタは、新しいオブジェクト(インスタンス)を作成するための特別な関数です。設計図から実際のモノを作り出す役割を持ちます。
JavaScriptでは、newキーワードと一緒に使用します。
// Dateコンストラクタでインスタンスを作成
const today = new Date();
// Arrayコンストラクタでインスタンスを作成
const numbers = new Array(1, 2, 3);
// URLコンストラクタでインスタンスを作成
const url = new URL("https://example.com");
newキーワードの意味
newキーワードは以下の処理を行います。
- 新しい空のオブジェクトを作成
- そのオブジェクトにプロパティやメソッドを設定
- 作成したオブジェクトを返す
// newを使った場合
const date1 = new Date();
console.log(typeof date1); // "object"
// newを使わない場合(Dateの場合は文字列が返る)
const date2 = Date();
console.log(typeof date2); // "string"
カスタムコンストラクタの作成例
自分でコンストラクタを定義することもできます。
class User {
// コンストラクタの定義
constructor(name, age) {
this.name = name;
this.age = age;
}
}
// コンストラクタを使ってインスタンスを作成
const user1 = new User("田中太郎", 25);
const user2 = new User("鈴木花子", 30);
console.log(user1.name); // "田中太郎"
console.log(user2.name); // "鈴木花子"
この例では、Userクラスのコンストラクタがnameとageを受け取り、新しいユーザーオブジェクトを作成します。
プロパティとは
プロパティの役割と定義
プロパティは、オブジェクトが持つデータや値です。オブジェクトの状態や特性を表します。
const user = new User("田中太郎", 25);
// プロパティの読み取り
console.log(user.name); // "田中太郎"
console.log(user.age); // 25
インスタンスプロパティ
インスタンスプロパティは、個々のインスタンスごとに異なる値を持ちます。
class Car {
constructor(brand, model, year) {
this.brand = brand; // インスタンスプロパティ
this.model = model; // インスタンスプロパティ
this.year = year; // インスタンスプロパティ
}
}
const car1 = new Car("Toyota", "Corolla", 2020);
const car2 = new Car("Honda", "Civic", 2021);
// 同じプロパティ名でも、インスタンスごとに値が異なる
console.log(car1.brand); // "Toyota"
console.log(car2.brand); // "Honda"
プロパティの読み取りと変更
プロパティは読み取りだけでなく、変更も可能です。
const url = new URL("https://example.com/old-path");
// プロパティの読み取り
console.log(url.pathname); // "/old-path"
// プロパティの変更
url.pathname = "/new-path";
console.log(url.pathname); // "/new-path"
プロパティの実例
JavaScriptの組み込みオブジェクトには多くのプロパティがあります。
const url = new URL("https://example.com:8080/path?id=123#section");
console.log(url.protocol); // "https:"
console.log(url.hostname); // "example.com"
console.log(url.port); // "8080"
console.log(url.pathname); // "/path"
console.log(url.search); // "?id=123"
console.log(url.hash); // "#section"
静的メソッドとは
静的メソッドの役割と定義
静的メソッドは、クラス自体に属する関数で、インスタンスを作成せずに直接呼び出せます。
// 静的メソッドの呼び出し(インスタンス不要)
const isValid = URL.canParse("https://example.com");
console.log(isValid); // true
// Array.isArrayも静的メソッド
console.log(Array.isArray([1, 2, 3])); // true
console.log(Array.isArray("not array")); // false
インスタンスメソッドとの違い
静的メソッドはnewでインスタンスを作らずに呼び出せますが、インスタンスメソッドはインスタンスが必要です。
// 静的メソッド: クラスから直接呼び出し
const max = Math.max(1, 5, 3); // インスタンス不要
// インスタンスメソッド: インスタンスから呼び出し
const text = "hello";
const upper = text.toUpperCase(); // インスタンス(text)が必要
静的メソッドの使用例
静的メソッドは、特定のインスタンスに依存しない、ユーティリティ的な機能に適しています。
class MathUtils {
// 静的メソッドの定義
static add(a, b) {
return a + b;
}
static multiply(a, b) {
return a * b;
}
static isEven(num) {
return num % 2 === 0;
}
}
// インスタンスを作らずに直接呼び出せる
console.log(MathUtils.add(5, 3)); // 8
console.log(MathUtils.multiply(4, 2)); // 8
console.log(MathUtils.isEven(10)); // true
なぜインスタンス不要で呼び出せるのか
静的メソッドは「クラスオブジェクト自身が持つメソッド」だからです。この仕組みについては後ほど詳しく説明します。
インスタンスメソッド(補足)
インスタンスメソッドとは
インスタンスメソッドは、インスタンスが持つ関数で、そのインスタンスのデータを操作します。
class User {
constructor(name, age) {
this.name = name;
this.age = age;
}
// インスタンスメソッド
greet() {
return `こんにちは、${this.name}です。`;
}
// インスタンスメソッド
isAdult() {
return this.age >= 20;
}
}
const user = new User("田中太郎", 25);
// インスタンスメソッドの呼び出し
console.log(user.greet()); // "こんにちは、田中太郎です。"
console.log(user.isAdult()); // true
静的メソッドとの比較
class Calculator {
constructor(initialValue) {
this.value = initialValue;
}
// インスタンスメソッド: インスタンスのデータを使う
addToValue(num) {
this.value += num;
return this.value;
}
// 静的メソッド: インスタンスのデータを使わない
static add(a, b) {
return a + b;
}
}
// 静的メソッド: インスタンス不要
console.log(Calculator.add(5, 3)); // 8
// インスタンスメソッド: インスタンス必要
const calc = new Calculator(10);
console.log(calc.addToValue(5)); // 15
インスタンスメソッドはthisを使ってインスタンスのプロパティにアクセスしますが、静的メソッドはthisを使いません。
3つの違いを整理する
コンストラクタ・プロパティ・静的メソッドの比較表
| 種類 | 使い方 | インスタンス | 役割 |
|---|---|---|---|
| コンストラクタ | new ClassName() |
作成する | オブジェクトの生成 |
| プロパティ | instance.property |
必要 | オブジェクトのデータ |
| インスタンスメソッド | instance.method() |
必要 | オブジェクトのデータを操作 |
| 静的メソッド | ClassName.method() |
不要 | クラス全体の機能 |
使い分けのポイント
コンストラクタを使う場面
- 新しいオブジェクトを作りたいとき
- 初期値を設定したいとき
プロパティを使う場面
- オブジェクトの状態を保存・参照したいとき
- オブジェクトごとに異なる値を持たせたいとき
インスタンスメソッドを使う場面
- オブジェクトのデータを使った処理をしたいとき
- オブジェクトの状態を変更したいとき
静的メソッドを使う場面
- 特定のインスタンスに依存しない処理をしたいとき
- ユーティリティ関数を提供したいとき
まとめ
JavaScriptのコンストラクタ、プロパティ、静的メソッドについて整理します。
コンストラクタ
-
newキーワードと共に使用 - 新しいオブジェクト(インスタンス)を作成
- 初期値の設定に使用
プロパティ
- オブジェクトが持つデータ
- インスタンスごとに異なる値を持つ
- アクセスにはインスタンスが必要
インスタンスメソッド
- インスタンスが持つ関数
- インスタンスのデータを操作
- アクセスにはインスタンスが必要
静的メソッド
- クラス自体が持つ関数
- インスタンス不要で呼び出し可能
- ユーティリティ関数として使用
これらの違いを理解することで、適切な設計ができるようになります。クラスを設計する際は、以下を考えましょう。
- どのデータをプロパティとして持つべきか
- どの処理がインスタンスのデータを必要とするか
- どの処理がインスタンスに依存しないか
この理解を深めることで、より読みやすく保守しやすいコードが書けるようになります。