JavaScriptにおける「Class.method」と「Class.prototype.method」の違い:分かりやすく解説
JavaScriptにおける「Class.method」と「Class.prototype.method」の違い:オブジェクト指向プログラミングとプロトタイプベースのプログラミングの観点から
JavaScriptは、オブジェクト指向プログラミング(OOP)とプロトタイプベースのプログラミングの要素を組み合わせています。そのため、クラスとプロトタイプに関する概念が混同されることがあります。この記事では、「Class.method」と「Class.prototype.method」の構文の違いと、それぞれがオブジェクト指向プログラミングとプロトタイプベースのプログラミングの観点からどのように関連しているのかを詳しく説明します。
クラスとプロトタイプ:基礎知識
1 クラス
JavaScriptにおけるクラスは、オブジェクトのテンプレートとして機能します。クラスには、コンストラクタとメソッドを定義することができます。コンストラクタは、新しいオブジェクトを作成するために使用されます。メソッドは、オブジェクトに対して実行できるアクションを定義します。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
2 プロトタイプ
JavaScriptにおけるプロトタイプは、オブジェクトの継承構造を定義します。すべてのオブジェクトは、プロトタイプチェーンと呼ばれる階層構造に属します。オブジェクトのプロトタイプは、そのオブジェクトに含まれていないプロパティやメソッドにアクセスできるようにします。
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
console.log(person1.name); // Alice
console.log(person2.age); // 25
person1.greet(); // Hello, my name is Alice and I am 30 years old.
person2.greet(); // Hello, my name is Bob and I am 25 years old.
Class.method vs. Class.prototype.method
1 Class.method:静的メソッド
「Class.method」構文は、静的メソッドを定義するために使用されます。静的メソッドは、クラス自体に関連付けられたメソッドです。静的メソッドは、オブジェクトのインスタンスを作成せずに直接呼び出すことができます。
class Person {
static isAdult(age) {
return age >= 18;
}
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const isAliceAdult = Person.isAdult(30);
console.log(isAliceAdult); // true
2 Class.prototype.method:インスタンスメソッド
class Person {
static isAdult(age) {
return age >= 18;
}
constructor(name, age) {
this.name = name;
this.age = age;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
const person1 = new Person('Alice', 30);
const person2 = new Person('Bob', 25);
person1.greet(); // Hello, my name is Alice and I am 30 years old.
person2.greet(); // Hello, my name is Bob and I am 25 years old.
オブジェクト指向プログラミングとプロトタイプベースのプログラミングとの関係
1 オブジェクト指向プログラミング
オブジェクト指向プログラミング(OOP)は、オブジェクトを中心にプログラムを設計するパラダイムです。オブジェクトは、データ(プロパティ)と行動(メソッド)をカプセル化したものです。OOPでは、継承を使用して、既存のクラスから新しいクラスを作成することができます。
2 プロトタイプベースのプログラミング
プロトタイプベースのプログラミングは、プロトタイプを使用して
JavaScriptにおける「Class.method」と「Class.prototype.method」の例:静的メソッドとインスタンスメソッドの比較
- 預金を行う
- 引き出しを行う
- 残高を確認する
静的メソッドを使用して、口座番号の生成というユーティリティ機能を追加します。
class BankAccount {
static generateAccountNumber() {
const randomDigits = Math.floor(Math.random() * 1000000) + 1000000;
return `BK-${randomDigits}`;
}
constructor(name, balance) {
this.name = name;
this.balance = balance;
this.accountNumber = BankAccount.generateAccountNumber();
}
deposit(amount) {
if (amount > 0) {
this.balance += amount;
console.log(`${amount}円を預けました。現在の残高は${this.balance}円です。`);
} else {
console.error('預金額は0円を超える必要があります。');
}
}
withdraw(amount) {
if (amount > 0 && amount <= this.balance) {
this.balance -= amount;
console.log(`${amount}円を引き出しました。現在の残高は${this.balance}円です。`);
} else {
console.error('引き出し金額は0円を超え、かつ残高を超えてはいけません。');
}
}
getBalance() {
console.log(`現在の残高は${this.balance}円です。`);
}
}
コードの説明
BankAccount
クラスは、name
、balance
、accountNumber
というプロパティを持つオブジェクトを作成します。generateAccountNumber
メソッドは、ランダムな口座番号を生成する静的メソッドです。constructor
メソッドは、新しい銀行口座オブジェクトを作成するために使用されます。deposit
メソッドは、口座に預金を行います。withdraw
メソッドは、口座から出金します。getBalance
メソッドは、口座の残高を表示します。
使用方法
const account1 = new BankAccount('Alice', 10000);
const account2 = new BankAccount('Bob', 5000);
console.log(account1.accountNumber); // BK-1234567
console.log(account2.accountNumber); // BK-8765432
account1.deposit(2000);
account2.withdraw(1000);
account1.getBalance(); // 現在の残高は12000円です。
account2.getBalance(); // 現在の残高は4000円です。
出力
BK-1234567
BK-8765432
2000円を預けました。現在の残高は12000円です。
1000円を引き出しました。現在の残高は4000円です。
現在の残高は12000円です。
現在の残高は4000円です。
BankAccount.generateAccountNumber()
は、静的メソッドとして定義されています。これは、BankAccount
クラス自体に関連付けられたメソッドであり、オブジェクトのインスタンスを作成せずに直接呼び出すことができます。account1.deposit(2000)
、account2.withdraw(1000)
、account1.getBalance()
、account2.getBalance()
はすべて、インスタンスメソッドとして呼び出されます。これらのメソッドは、account1
とaccount2
というオブジェクトのインスタンスに対して呼び出されています。
この例は、「Class.method」と「Class.prototype.method」構文の使用方法と、それぞれがオブジェクト指向プログラミングとプロトタイプベースのプログラミングの観点からどのように関連しているのかを理解するのに役立ちます。
JavaScriptにおける「Class.method」と「Class.prototype.method」の代替方法
アロー関数は、簡潔で読みやすいコードを書くために使用できる代替方法です。インスタンスメソッドを定義する際に、以下の構文を使用できます。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
greet = () => {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
};
}
長所
- コードが簡潔で読みやすい
this
キーワードの自動バインディング
短所
- コンストラクタ内でのみ使用できない
- 静的メソッドの定義には使用できない
シンボルは、オブジェクトのプロパティやメソッドを一意に識別するために使用できる代替方法です。シンボルを使用してインスタンスメソッドを定義する際に、以下の構文を使用できます。
const greetSymbol = Symbol('greet');
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
[greetSymbol]() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
- プロパティやメソッド名の衝突を回避できる
- プライベートなメンバーを定義できる
- シンボルのサポートに古いブラウザは対応していない
クラスのプロパティを使用して、静的メソッドとインスタンスメソッドを定義することができます。以下の構文を使用できます。
class Person {
constructor(name, age) {
this.name = name;
this.age = age;
}
static isAdult(age) {
return age >= 18;
}
greet() {
console.log(`Hello, my name is ${this.name} and I am ${this.age} years old.`);
}
}
- 構文がシンプルで分かりやすい
- アロー関数やシンボルほど柔軟ではない
「Class.method」と「Class.prototype.method」構文は、JavaScriptでクラスとプロトタイプを操作するための標準的な方法です。しかし、アロー関数、シンボル、クラスのプロパティなど、状況に応じて他の方法を使用することも検討できます。それぞれの方法の長所と短所を理解し、適切な方法を選択することが重要です。
補足
- 上記の代替方法は、互いに排他的ではありません。組み合わせて使用することもできます。
- 新しい構文を使用する場合は、ブラウザの互換性を考慮する必要があります。
javascript oop prototype-programming