JavaScriptのプロトタイプの継承を利用する


7

JavaScriptには、オブジェクトが他のオブジェクトから直接プロパティを継承するクラスフリーのオブジェクトシステムがあります。これは本当に強力ですが、古典的な訓練を受けたプログラマーには馴染みがありません。古典的なデザインパターンをJavaScriptに直接適用しようとすると、イライラします。しかし、JavaScriptのプロトタイプの性質で作業することを学ぶ場合、あなたの努力は報われるでしょう。
...
それはCの服を着たLispです。

- ダグラス・クロックフォード

これは、キャンバスとHTML5を使用するゲーム開発者にとって何を意味しますか?私はゲームでの有用なデザインパターンについてこの質問を見てきましたが、プロトタイプの継承はクラシックの継承とは大きく異なり、これらの一般的なパターンのいくつかを適用する最良の方法には確かに違いがあります。

例えば、古典の継承は、私たちが作成することを可能にするmoveableEntityクラスを、その私たちのゲームの世界で動く(任意のクラスであることを拡張playermonsterbullet、など)。もちろん、JavaScriptを強化してそのように動作させることはできますが、そうすることで、その性質との戦いのようなものになります。指先にプロトタイプの継承がある場合、この種の問題へのより良いアプローチはありますか?

回答:


8

最新のJSエンジンを使用してJavaScriptから適切なパフォーマンスを得るには、一般的な構造型またはダック型のパターンを反映するコードを記述する必要があります。構造タイピングは、継承のみでタイプを提供するよりも強力ですが、ゲームで使用されるデザインパターンを実際には変更しません。

例として、C ++またはJavaでは、通常、継承によって型付けを行いますが、MVCを実装するために、通常、複数のインターフェイス/仮想クラスを持つ深い型階層があります。しかし、ゲームが扱うデータの種類をモデル化するのに実際には役立たないため、ゲームはすでにこの種のデザインパターンを避けています。

コンテキストオブジェクト、コンポーネント、フライウェイト、戦略など、ゲームデザインで最も役立つパターンは、C ++などの言語で実装されている場合でも、最初から複雑な継承階層を使用する傾向はありません。コンポーネントには単一の仮想クラスが含まれます(最大で)。Flyweightは通常、テンプレートを介したC ++の(扱いにくい)構造型指定を使用します。ストラテジーでは、パフォーマンスまたはプログラマーの健全性のために、何らかの形の型消去を使用することがよくあります。

これに対する1つの例外は、プロトタイプパターン自体です。これは、特にデザイナー主導のデータの場合、ゲームで何らかの形でよく見られます。JavaScriptを使用すると、このパターンは簡単になります。しかし、連想データ構造をサポートする言語で実装することは、少なくとも不十分では、特に難しいパターンではありません。JSを使用すると、基盤となるエンジンのオプティマイザーを活用できるため、JSをより多く使用できるようになります。しかし、それが実際に1つのプログラムの方法を変えるかどうかはわかりません。単純なプロトタイプパターンは、パフォーマンスがよくないにもかかわらず、多くのゲームの多くの場所にすでに存在しています。


3
これを投稿して1分もしないうちに賛成票をもらいました。これを読んで、適切な回答かどうかを判断するのに十分な時間だとは思いません。一部の人々が、ひどい文法を使わずに長く、書かれた回答を単に賛成しているといういくつかの兆候を見てきました。しないでください。

この特定の答えは、経験豊富な開発者にとっては真実です。私もそれを読んだとき、「ええ、ええ、いつもこのように機能します」のようなものなので、私はほとんどすぐに賛成しました。
Nevermind '17年

よく言った!JSは、ゲームで非常に一般的であるが、自分自身を明確にすることができない種類のデータ駆動型およびコンポーネントアプローチに非常に適しているといつも感じていました:)
oberhamsi

6

実際にセマンティクスを掘り下げると、JavaScriptは実際にはSelfのような「実際の」プロトタイプ言語よりもほとんどのクラスベースの言語に少し近いことがわかります。new動作する方法は、ほとんどの場合、独自のフィールドに状態を含み、プロトタイプのフィールドにメソッドを含むオブジェクトを作成することです。目を細めて、それがクラスです。

本当にプロトタイプになるには、はありませんnew。オブジェクトのクローンを作成し、差分継承を行っています。

したがって、JavaScriptのハーフプロトタイプの性質についてあまり心配しないでください。3つの要素を理解するだけです。

  1. ほとんどの場合、オブジェクトは本質的に「クラス」のインスタンスであり、コンストラクターはフィールドをprototype定義し、コンストラクターの関数はメソッドを定義します。

  2. 使い慣れたJava / C#スタイルの単一継承が必要な場合は、プロトタイプをチェーンすることで取得できます。そこにあるほとんどのJSフレームワーク(Closure、dojoなど)には、それを接続するための素晴らしいヘルパーメソッドがあります。

  3. メソッドはいつでも「クラス」に追加できます。プロトタイプが必要とする関数を自由に混ぜてください。常に継承チェーンと複雑な階層を設定する必要はありません。同じメソッドを必要とするクラスが10個ある場合、それらを常に10個のクラスに強制的に追加できます。


私は物事の第三の方法が好きです。たとえば、ヘルス属性とDamage()メソッドを追加する「破損可能な」関数を作成できます。次に、センチネルの「isDamageable」タイプの値ではなく、実際のデータ/メソッドの存在に基づいて、他のコードをダックタイプすることができます。
drhayes 2011年

1
その通りです。多くの機能を果たす "ミックスイン"を提供する一連のJSフレームワークがあります。特定のプロトタイプに一連の関数を追加します。
立派な
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.