prototype-pattern について
複数のオブジェクト間でプロパティやメソッドを共有する JavaScript のプロトタイプパターンを解説するスキルです。ES6 クラス、プロトタイプチェーン、継承、Object.create() を扱います。
主な機能
- 01プロトタイプ経由でメソッドを共有
- 02ES6 クラスと extends を使用
- 03Object.create() でオブジェクトを作成
- 04プロトタイプチェーンの探索を理解
- 05インスタンスメソッドの重複を回避
活用シーン
- 01複数のインスタンス間でメソッドを共有
- 02オブジェクト型間の継承を設計
- 03JavaScript のプロトタイプ探索を学習
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ patternsdev/ skills --skill prototype-patternインストール後、Claude Code で/prototype-patternを入力して読み込まれたか確認します。
詳細
プロトタイプパターン
プロトタイプパターンは、同じ種類の多くのオブジェクト間でプロパティを共有するのに便利な方法です。プロトタイプは JavaScript に組み込まれたオブジェクトで、プロトタイプチェーンを通じてオブジェクトからアクセスできます。
アプリケーションでは、同じ種類のオブジェクトをたくさん作成する必要がよくあります。その便利な方法のひとつが、ES6 クラスのインスタンスを複数作成することです。
使用する場面
- 多くのオブジェクトでメソッドを重複させずに共有する必要がある場合に使用します
- JavaScript の継承モデルと ES6 クラスを理解するのに役立ちます
手順
- ES6 クラスを使用して、メソッドを自動的にプロトタイプに追加します
Object.create()を使用して、特定のプロトタイプを持つオブジェクトを作成します- 継承にはプロトタイプチェーンを活用します(ES6 クラスの
extendsキーワード) - プロトタイプ上のプロパティは共有され、インスタンスごとに複製されないことを理解します
詳細
たくさんの犬を作りたいとしましょう!この例では、犬にできることはあまりありません。名前があり、吠えるだけです!
class Dog {
constructor(name) {
this.name = name;
}
bark() {
return `Woof!`;
}
}
const dog1 = new Dog("Daisy");
const dog2 = new Dog("Max");
const dog3 = new Dog("Spot");
ここでは、constructor に name プロパティがあり、クラス自体に bark プロパティがあることに注目してください。ES6 クラスを使用すると、クラス自体で定義されたすべてのプロパティ(この場合は bark)が、自動的に prototype に追加されます。
コンストラクターの prototype プロパティ、または任意の インスタンス の __proto__ プロパティにアクセスすることで、prototype を直接確認できます。
console.log(Dog.prototype);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
console.log(dog1.__proto__);
// constructor: ƒ Dog(name, breed) bark: ƒ bark()
コンストラクターのインスタンスにある __proto__ の値は、コンストラクターのプロトタイプへの直接参照です!オブジェクト上に存在しないプロパティにアクセスしようとすると、JavaScript はそのプロパティがプロトタイプチェーン内にあるかどうかを確認するため、プロトタイプチェーンをたどります。
プロトタイプパターンは、同じプロパティにアクセスできる必要があるオブジェクトを扱うときに非常に強力です。プロパティを毎回複製する代わりに、すべてのインスタンスがプロトタイプオブジェクトにアクセスできるため、そのプロパティをプロトタイプに追加するだけで済みます。
すべてのインスタンスがプロトタイプにアクセスできるので、インスタンスを作成した後でも、プロトタイプにプロパティを簡単に追加できます。
犬には吠えるだけでなく、遊ぶこともできてほしいとしましょう。プロトタイプに play プロパティを追加すれば、それを実現できます。
プロトタイプチェーンという用語は、複数の段階があることを示しています。そのとおりです!ここまでは、__proto__ が参照する最初のオブジェクトに直接存在するプロパティへのアクセス方法だけを見てきました。しかし、プロトタイプ自体も __proto__ オブジェクトを持っています!
別の種類の犬、スーパードッグを作ってみましょう。この犬は通常の Dog からすべてを継承し、さらに飛ぶこともできる必要があります。Dog クラスを拡張して fly メソッドを追加すれば、スーパードッグを作成できます。
class SuperDog extends Dog {
constructor(name) {
super(name);
}
fly() {
return "Flying!";
}
}
Dog クラスを拡張したため、bark メソッドを利用できます。SuperDog のプロトタイプにある __proto__ の値は、Dog.prototype オブジェクトを指しています!
これで、なぜプロトタイプ チェーン と呼ばれるのかが明らかです。オブジェクトに直接存在しないプロパティにアクセスしようとすると、JavaScript はそのプロパティが見つかるまで、__proto__ が指すすべてのオブジェクトを再帰的にたどります!
Object.create
Object.createメソッドを使うと、新しいオブジェクトを作成し、そのプロトタイプの値を明示的に渡すことができます。
const dog = {
bark() {
return `Woof!`;
},
};
const pet1 = Object.create(dog);
pet1自体にはプロパティがありませんが、プロトタイプチェーン上のプロパティにはアクセスできます。dogオブジェクトをpet1のプロトタイプとして渡したため、barkプロパティにアクセスできます。
Object.createは、新しく作成するオブジェクトのプロトタイプを指定することで、オブジェクトがほかのオブジェクトからプロパティを直接継承できるようにするシンプルな方法です。新しいオブジェクトは、プロトタイプチェーンをたどることで新しいプロパティにアクセスできます。
プロトタイプパターンを使うと、オブジェクトがほかのオブジェクトのプロパティにアクセスし、継承できるように簡単に設定できます。プロトタイプチェーンを使えば、オブジェクト自体に直接定義されていないプロパティにもアクセスできるため、メソッドやプロパティの重複を避け、使用するメモリ量を削減できます。