1

(より良い質問タイトルのために編集を開いてください-私が探しているものを表現するのは困難でした)

やあ、

私はプロトタイプを扱ってきましたが、最近、関連する関数をグループ化するためにプロトタイプ内に名前空間が必要であることに気付きました。最も単純な形式のコードは、次のようになります。

// Base grid functions.
Grid.prototype = {

    init: function init() {
        document.getElementById("output").innerHTML += "<br>" + this.id;

        this.Rows.init();

        this.Test.init();

        document.getElementById("output").innerHTML += "<br><br>";
    },

    Test: {
        init: function init() {
            document.getElementById("output").innerHTML += "<br>" + this.id;
        }
    }

};

// Additional row-related and row utility functions.
Grid.prototype.Rows = {

    init: function init() {
        document.getElementById("output").innerHTML += "<br>" + this.id;
    }
};

私の「名前空間」では、開発者が(呼び出しまたは適用を介して)毎回コンテキストを渡す必要なしに、たとえばのような関数を呼び出すことができるようにRows、のコンテキストを維持したいと思いました。thisgridInstance.Rows.get()

これを行うために、私はLoDashの_.bind関数を使用して、新しいGridインスタンスごとに、その行に関連する各関数のコンテキストを設定しました。

Test「名前空間」は、プロトタイプ内にネストされたときにGrid、異なる結果になるかどうかを確認するためだけのものであることに注意してください。

var Grid = function Grid(id) {
    var t = this;

    // Assign an id to the control.

    if (!id) {
        // Assign a custom id if the control does not have one.
        id = "grid-" + new Date().getTime();
    }

    t.id = id;

    _.each(t.Rows, function (rowFn, key) {
        t.Rows[key] = _.bind(rowFn, t);
    });

    _.each(t.Test, function (rowFn, key) {
        t.Test[key] = _.bind(rowFn, t);
    });

    t.init();
};

ここにフィドルがあり、出力を示しています。

x x x

y x x

z x x

私の質問は、Rowsプロトタイプが新しいものとしてインスタンス化されないのはなぜですか(Grid.prototype呼び出すたびにnew Grid()、これを回避するにはどうすればよいですか? )

追加の考え

私の考えでは、新しいインスタンスGrid.prototypeの青写真として機能し、その一部として名前空間が含まれると考えていました。GridRows

したがって、Gridコンストラクターで、の新しいコンテキストを適用するthisthis.Rowsthis.Rows最初は、Grid.prototype.Rowsそのインスタンスにのみ属するブループリントの参照ではなく、コピーになります。

コンストラクターでは、たとえば、プロトタイプ自体ではなく、のコンテキストにバインドされるGridように変更することになると思いました。this.Rowsthis

回答を投稿

プロトタイプが、オブジェクトの青写真として使用されるのではなく、プロトタイプを継承するすべてのオブジェクトによって参照されることを忘れていたため、私の追加の考えはばかげていました。

ここでのフィドルはその要点を示しています。

4

1 に答える 1

1

それがプロトタイプの目的であるためです。そのメンバーはすべて、インスタンスごとに同じです。たとえば、Grid init関数を呼び出すこともできますthis.Rows = Object.create(Grid.prototype.Rows);が、自分で呼び出す必要があります。JavaScriptは、すべてのグリッドインスタンスに新しいインスタンスが必要であることを認識していません。

于 2013-03-12T11:36:03.073 に答える