ファクトリ関数
クロージャを使ってプライベートな状態を持つオブジェクトを作成します。
「ファクトリ関数」は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フィードバックを取得できます。ローカル設定は不要です。