2

私がやろうとしているのは、子オブジェクトに、ベースオブジェクトで定義された関数の独自の実装を提供させることです。私がこれまで理解してきた限りでは、プロトタイプはこれを行うための最良の(唯一の!)方法です。

また、私は現在ゲームエンジンTurbulenzを使用して開発していることにも注意してください。そのため、私は可能な限り彼らのスタイルに忠実に従うように努めています。エンジンでは、「クラス」/オブジェクトは次の方法で定義および作成されます。

function baseObject() { }
baseObject.prototype = 
{
    myMember1: 1,
    myMember2: 2,

    myMethod: function myMethodFn() {
        return this.myMember1 + this.myMember2;
    }
}

baseObject.Create = function baseObjectCreateFn
{
    var o = new baseObject();
    return o;
}

これにより、次のことが可能になります

var anObject = baseObject.Create();
var someValue = anObject.myMethod(); // should return 3

ここで実行できるようにしたいのは、baseObjectのすべてのプロパティを継承する新しいオブジェクトを作成すると同時に、myMethod関数を上書きして、たとえば、加算ではなく2つのメンバー値を減算できるようにすることです。

別のオブジェクトを作成してからそのプロトタイプを変更する必要があると言ったのは正しいでしょうか?私を最も悩ませているのは、baseObjectのプロトタイプの定義がオブジェクトリテラルとして定義されているため、そのメンバーの1つを上書きする構文がわからないことです。つまり、次のようになりますか?:

function childObject() {}

childObject.prototype = baseObject.Create() // would this inherit from baseObject?
// or should it be: childObject.prototype = new baseObject();

// this is the part thats confusing me as the syntax 
// doesn't quite match the original base objects prototype 
// syntax and I'm unsure if that will matter
childObject.prototype.myMethod = function myMethodFn() {
    return this.myMember1 - this.myMember2;
} 

childObject.Create = function childObjectCreateFn
{
    var o = new childObject();
    return o;
}

var aChildObject = childObject.Create()
var anotherValue = aChildObject.myMethod() // would this return -1 as expected?

要約すると、ベースオブジェクトから関数を継承して変更することにより、ベースオブジェクトに存在する関数を上書きするオブジェクトを作成しようとしていますが、これを行うにはどうすればよいですか?御時間ありがとうございます。

4

1 に答える 1

1

あなたはそれが正しいです。

構文の混乱に関しては、実際の違いはありません

thing.prototype.myMethod = function () { ... }

thing.prototype = { myMethod: function() { ... } };

ただし、2番目の例では、プロトタイプを一度にオブジェクトリテラルに)設定し、再度設定すると、プロトタイプを新しいオブジェクトリテラルで一度に上書きします。ただし、これはオブジェクトリテラルであるため、この方法で継承を行うことはできません(裸の中括弧で宣言されたものはすべて、特別なタイプ{ ... }のインスタンスにすぎObjectません)。最初の構文に固執すれば、いつでも大丈夫です。

あなたが置くとき:に注意してください:

childObject.prototype.myMethod = function myMethodFn() { ... }

あなたが置いた部分myMethodFnは実際には無視されます。関数の名前myMethodは、これが割り当てた場所であるという事実に基づいています。

同様に、あなたが持っているところ

childObject.Create = function childObjectCreateFn

必要はありませんchildObjectCreateFn(無視されます)。かっこを()後のどこかに置く必要があります。そうしないとfunction、構文エラーになります。

これが機能する理由に移ると、Javascriptで作成されたすべてのオブジェクトにはプロトタイプがあります。そのオブジェクトでメソッドを呼び出すと、最初にオブジェクト自体の内部を調べて、メソッドの名前に対応するキーが存在するかどうかを確認します。そうでない場合は、プロトタイプオブジェクトで同じものを探し、存在しない場合は、そのオブジェクトのプロトタイプに移動し、Objectプロトタイプのないルートに到達するまで続きます。

このようにして、同じ名前を付けるだけで実装をオーバーライドできますが、プロトタイプチェーンの早い段階で実装を表示します。それはまさにあなたがしていることですchildObjectbaseObjectのプロトタイプとして機能するbaseObjectのインスタンスを作成したため、の機能は保持されますchildObjectchildObject次に、同じ名前の新しいメソッドでプロトタイプを拡張しましたが、プロトタイプチェーンの早い段階にあります。

于 2013-02-16T04:21:25.000 に答える