0Pricing
JavaScript Academy · レッスン

ファクトリ関数

クロージャを使ってプライベートな状態を持つオブジェクトを作成します。

「ファクトリ関数」はCoddyKit上の無料JavaScript Academyレッスンです。 これはレッスン4/4です。 下記で完全なレッスンを無料で読むことができます。その後、ブラウザ内の組み込みコードエディタと24時間対応のAIチューターでハンズオン演習できます。 これはJavaScript Academy学習パスの一部であり、ウェブとCoddyKitアプリ全体で進捗が同期されます。 JavaScript Academyコースには全4レッスンが含まれています。

ファクトリー関数とは

ファクトリー関数とは、新しいオブジェクトを返す関数です。コンストラクターとは異なり、通常どおり呼び出し(newは使い)ます。また、クロージャを使ってprivateな状態を持たせることもできます。

function createUser(name) {
  return {
    name,
    greet: () => "Hi, I am " + name
  };
}
const u = createUser("Ada");
console.log(u.greet()); // "Hi, I am Ada"

newキーワードを使わない

ファクトリー関数を使うと、newやthisにまつわる落とし穴を避けられます。関数をそのまま呼び出すだけで、オブジェクトが返されます。

function point(x, y) {
  return { x, y };
}
const p = point(3, 4);
console.log(p.x, p.y); // 3 4

クロージャによるprivateな状態

ファクトリー内で宣言した変数はprivateです。返されたオブジェクトのメソッドがそれらを取り込みます。これはモジュールパターンと同じ仕組みですが、複数のインスタンスを作成できます。

function createCounter() {
  let count = 0; // private
  return {
    inc: () => ++count,
    get: () => count
  };
}
const c = createCounter();
c.inc();
console.log(c.get()); // 1

多数の独立したインスタンス

ファクトリーを呼び出すたびに、独自のprivateな状態を持つ新しいオブジェクトが作られます。これがシングルトンであるモジュールとの大きな違いです。

function createCounter() {
  let n = 0;
  return { inc: () => ++n };
}
const a = createCounter();
const b = createCounter();
console.log(a.inc(), a.inc()); // 1 2
console.log(b.inc());          // 1

計算されたプロパティ

ファクトリーでは作成時に値を導出し、計算結果を返すメソッドとして公開できます。その際、入力値をprivateに保てます。

function rectangle(w, h) {
  return {
    area: () => w * h,
    perimeter: () => 2 * (w + h)
  };
}
const r = rectangle(3, 4);
console.log(r.area());      // 12
console.log(r.perimeter()); // 14

デフォルトと省略可能な設定

ファクトリーは通常の関数なので、分割代入を使ってデフォルト値やオプションを簡潔に扱えます。

function createButton({ label = "OK", disabled = false } = {}) {
  return { label, disabled };
}
console.log(createButton());             // { label: "OK", disabled: false }
console.log(createButton({ label: "Go" })); // { label: "Go", disabled: false }

継承よりコンポジション

ファクトリーはコンポジションを重視します。クラスの継承階層を拡張するのではなく、振る舞いを組み合わせてオブジェクトを構築します。

const canFly = (s) => ({ fly: () => s.name + " flies" });
function createBird(name) {
  const self = { name };
  return Object.assign(self, canFly(self));
}
console.log(createBird("Robin").fly()); // "Robin flies"

共有する振る舞い

インスタンスごとのコピーを作らずにメソッドを共有するには、メソッドを一度だけ定義して割り当てます。あるいは、クロージャがもたらすプライバシーのために、わずかなコストを受け入れることもできます。

const behavior = {
  describe() { return "id " + this.id; }
};
function createItem(id) {
  return Object.assign({ id }, behavior);
}
console.log(createItem(7).describe()); // "id 7"

関数も返す

より分かりやすいインターフェースになる場合は、ファクトリーからオブジェクトではなく関数を返すこともできます。その場合もprivateな状態を取り込めます。

function multiplier(factor) {
  return (n) => n * factor;
}
const triple = multiplier(3);
console.log(triple(5)); // 15

ファクトリーとコンストラクター

コンストラクターはnew、this、プロトタイプチェーンを使います。ファクトリーはよりシンプルで、thisに関するバグを避けられ、クロージャによる本当のプライバシーも実現できます。その代わり、プロトタイプ上でメソッドを共有することはできません。

作成時のバリデーション

ファクトリーでは、オブジェクトを返す前に入力値を検証し、エラーを投げたり正規化したりできます。これにより、作られるすべてのオブジェクトが有効であることを保証できます。

function createAge(value) {
  if (value < 0) throw new Error("age must be >= 0");
  return { value };
}
console.log(createAge(30).value); // 30

クイックチェック

ファクトリー関数

まとめ

ファクトリー関数はnewやthisを使わずにオブジェクトを返し、クロージャによってprivateな状態を実現します。呼び出すたびに独立したインスタンスが作られるため、計算されたプロパティ、デフォルト設定、コンポジション、バリデーションを利用できます。プロトタイプによるメソッド共有と引き換えに、シンプルさと本当のプライバシーを得られる、コンストラクターに代わるクロージャベースのすっきりした方法です。

よくある質問

「ファクトリ関数」レッスンは無料ですか?

はい。「ファクトリ関数」の完全なテキストはこのウェブで無料で読めます。インタラクティブに演習し(組み込みコードエディタと24時間対応のAIチューター)、JavaScript Academyコースの残りをアンロックするには、CoddyKit PROにアップグレードしてください。 JavaScript Academyコースには全4レッスンが含まれています。

「ファクトリ関数」で何を学びますか?

クロージャを使ってプライベートな状態を持つオブジェクトを作成します。 ブラウザで直接実行するハンズオンコードでJavaScript Academyを演習し、24時間対応のAIチューターがレッスンを進める中での質問に答えます。

JavaScript Academyを始めるのに経験は必要ですか?

事前経験は必要ありません。CoddyKitのJavaScript Academyは初級者から上級者向けに構成されているため、ここから始めるか最初から始めて、自分のペースで進むことができます。 これはレッスン4/4です。

「ファクトリ関数」レッスンにはどのくらい時間がかかりますか?

ほとんどのCoddyKitレッスンは約5~10分かかります。各レッスンはコンパクトでインタラクティブなので、着実に進歩し、ウェブとアプリ全体で正確に前回の場所から再開できます。

このJavaScript Academyレッスンでコードを書いて実行できますか?

はい。すべてのJavaScript Academyレッスンに組み込みコードエディタが含まれているため、ブラウザでリアルコードを書いて実行し、即座のAIフィードバックを取得できます。ローカル設定は不要です。

このコースのすべてのレッスン

  1. クロージャが状態を取り込む仕組み
  2. クロージャによるプライベート変数
  3. モジュールパターン(IIFE)
  4. ファクトリ関数
← JavaScript Academyに戻る