3

[編集済み: vector2dandvector3dは良い例ではありません。現在、代わりにptandを使用していptMassます。]

私はこれに対する答えを探してきましたが、利用できる良い解決策はないようです。

以下のようなオブジェクトがあるとします。

function pt(x,y){
    this.x = x;
    this.y = y;
}

さて、以下のような点質量が欲しいです。

function ptMass(x,y,m){
    this.x = x;
    this.y = y;
    this.m = m;
}

継承を使用してptMassクラスを作成することをお勧めします。

私は現在、それを行うために次の方法を使用しています。

function ptMass(x,y,m){
    pt.apply(this.arguments);
    this.m = m;
}

でこれを行う方法はありprototypeますか? 以下を試してみましたが、うまくいきません。

pt = function(m){this.m = m};
ptMass.prototype = new pt();

もう 1 つの質問ですが、プロトタイプの継承を使用することの進歩は何ですか?

4

2 に答える 2

3

まず、なぜ継承した方が良いのでしょうか。
私自身は構成 (モジュール/コンポーネントと依存関係の注入) を好みますが、継承についていくつかの議論があります。

次に、次のことを行うことで再利用できます。

function Vector2D (x, y) {
    this.x = x;
    this.y = y;
}


function Vector3D (x, y, z) {
    Vector2D.call(this, x, y);
    this.z = z;
}

第 3 に、数万 (または数百万) のポリゴンを作成する大規模な JS アプリでは、余分な関数呼び出しが不必要に遅くなります。

第四に、あなたは使用できません

Vector3D.prototype = new Vector2D();

まず、 Vector2D 内の何も初期x化していません。 第二に、他の言語から来ている場合は、STATICプロパティと関数を保持するためのものです。y
prototype

初期化したとしても、Vector3D クラスのすべてのインスタンスでまったく同じ Vector2D になりVector2Dます。

それだけではない理由:

var point2D = function (x, y) {
        return { x : x,
                 y : y  };
    },
    point3D = function (x, y, z) {
        return { x : x,
                 y : y,
                 z : z };
    };

...そして、これらの特定の構成要素を基本要素として使用する場合、それらを使用するさまざまなモジュールを構成しますか?


編集

function anObj (x, y) {
    var privateFunc = function () { return y; };

    return {
        x : x,
        method : function () { return privateFunc(); }
    };
}


var myObj = anObj(1, 2);
myObj.x;        // 1
myObj.method(); // 2

ここでの利点は、プライベート変数 (privateFuncおよびy) を取得したことです。
欠点は、メモリ使用量に関して、オブジェクトの各インスタンスがプライベート メソッドの独自のコピーを持つ必要があることです。
したがって、何十万ものこれらのオブジェクト (頂点/ポリゴンなど) を作成していて、それらがプライベートな状態を持つ必要がない場合、これは使用する方法ではありません。

ただし、プレイヤー、敵、コントローラー、または改ざんしたくないものを作成している場合は、このような (またはより高度な) メソッドを使用する必要があります。

100% プライベートでもあるSTATICデータ/メソッドが必要な場合は、次のような形式を試してください。

var objectMaker = (function () {
    var staticData = 32,
        staticFunc = function (num) { return num + staticData; };

    return function (x, y) {
        var privateData = 12,
            privateMethod = function (num) {
                return y + privateData + staticFunc(num);
            };

        return { x : x,
                 method : function (num) { return privateMethod(num); }
        };
    };
}());


var myObj = objectMaker(3, 4);
myObj.x;          // 3;
myObj.method(12); // 12 + y(y === 4) + privateData + staticData;

つまり、ここで実行したことは、即時起動関数を取得したことです (定義されるとすぐに起動し、関数のを変数に返します)。
したがって、この特定のケースでは、この関数は、新しいインスタンスを作成するために使用する実際の関数をすぐに返します。

(返されるコンストラクターではなく) 即時関数の内部にあるプライベート変数と関数は静的です。つまり、作成するすべてのインスタンスは、そのクロージャー内のまったく同じ関数/データにアクセスできます。
欠点は、これらの静的関数がプライベート(またはインスタンス固有の) データにアクセスできないことです。
これは、インスタンス値を変更するために静的メソッドに依存できないため、値を静的関数に渡し、静的関数からの戻り値をキャッチする必要があることを意味します (技術的には、オブジェクト/配列を直接変更することができますそれらを関数に渡しますが、それ以外の場合は戻り値をキャッチする必要があります)。

これで、インスタンス間で共有される多くのヘルパー関数 (低メモリ) を、プライベートで安全なままにすることができます。

必要なものがパブリック プロパティ、パブリック メソッド、および静的メソッド/プロパティである場合は、次のようにアクセスできます。

var Obj = function (x, y) {
    this.x = x;
    this.per_instance_method = function () { return y; };
};

Obj.prototype.staticData = { z : 32 };
Obj.prototype.staticMethod = function () { return this.x + this.staticData.z; };

var myObj = new Obj(3, 4);
myObj.staticMethod();

...プロトタイプメソッドがインスタンスのプライベートデータ( など)にアクセスできるとは思わないでくださいy

于 2012-11-29T15:54:27.463 に答える
1

いいえ、あなたの最初のものはほぼ正しかったです:

function vector3d(x,y,z){
    vector2d.apply(this, arguments);
    // you might also use vector2d.apply(this, [].slice.call(arguments, 0,2));
    // or simpler vector2d.call(this, x, y);
    this.z=z;
}

はい、コンストラクターから呼び出す必要があります。プロトタイプオブジェクトを作成するために一度呼び出すと、継承が正しく設定されますが、インスタンスが作成されますが、vector2Dこれは必要でもなく、望んでもいません。害を及ぼすことさえあります。What is the reason [not] to use the 'new' keyword [for inheritance] ?の詳細な回答をご覧ください。.

プロトタイプでこれを行う方法はありますか?

vector3d.prototype = Object.create(vector2d.prototype);

vector3は、継承のすべてのインスタンスがのプロトタイプ オブジェクトから継承するプロトタイプ オブジェクトを作成しますvector2d。それが必要かどうかはわかりませんが、通常の 2 次元の方法は 3 次元のベクトルには適用されません。

プロトタイプの継承を使用することの進歩は何ですか?

于 2012-11-29T15:56:27.950 に答える