JavaScriptにおける「Class.method」と「Class.prototype.method」の違い:分かりやすく解説

2024-07-02

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クラスは、namebalanceaccountNumberというプロパティを持つオブジェクトを作成します。
  • 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()はすべて、インスタンスメソッドとして呼び出されます。これらのメソッドは、account1account2というオブジェクトのインスタンスに対して呼び出されています。

この例は、「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


レスポンシブWebデザインに必須!JavaScript ウィンドウリサイズイベントの活用法

JavaScript ウィンドウリサイズイベントは、ブラウザウィンドウのサイズが変更されたときに発生するイベントです。このイベントは、ウィンドウのサイズに依存する要素を動的に調整したり、ユーザーの操作に合わせたレイアウト変更を行ったりするのに役立ちます。...


jQueryを使いこなすための必須テクニック!名前属性で要素を自由自在に操る

このチュートリアルでは、jQueryを使用して要素を名前属性で選択する方法について説明します。名前属性とはHTML要素には、さまざまな属性を付加することができます。名前属性はその一つで、フォーム要素などで入力項目を識別するために使用されます。...


もう迷わない! JavaScriptでネストオブジェクト・配列にアクセスする3つの方法と注意点

そこで、文字列パスと呼ばれる手法が役立ちます。文字列パスは、ドット . 記法を使用して、ネストされたオブジェクトと配列の階層を表現する文字列です。この方法を使用すると、コードをより簡潔で読みやすくし、メンテナンスしやすくなります。次の例では、文字列パスを使用してネストされたオブジェクトにアクセスする方法を示します。...


チェックボックスのチェック状態変更イベントを使いこなしてインタラクティブなWebページを作成しよう

チェックボックスのチェック状態変更イベントには、主に以下の2種類があります。changeイベント: チェックボックスのチェック状態が変更されたときに発生します。イベントハンドラは、イベントが発生したときに実行される関数を指します。jQueryを使用してイベントハンドラを登録するには、以下の方法があります。...


【エンジニア必見】React、JSX、ESLintの三角関係を解決!「JSX not allowed in files with extension '.js' with eslint-config-airbnb」の謎を解き明かす

AirbnbのESLint設定では、デフォルトで**.jsx**拡張子のファイルのみでJSXの使用を許可しています。しかし、.js拡張子のファイルでもJSXを使用したい場合があります。この問題を解決するには、以下の2つの方法があります。方法1:.js拡張子のファイルでもJSXの使用を許可する...


SQL SQL SQL SQL Amazon で見る



__proto__とprototypeの違い

proto とは?proto は、オブジェクトのプロトタイプチェーンの次のオブジェクトへの直接参照です。つまり、あるオブジェクトがプロパティやメソッドにアクセスできない場合、proto によって参照される別のオブジェクトから継承しようとする仕組みです。