1

私はかなり大規模なJSプロジェクトでいくつかの作業を開始しており、コードをクリーンかつ効率的に構造化することを確認したいと考えています。私はJSでのOOPへのさまざまなアプローチを読んでいますが、本当に好きなものは見つかりませんでした。

プロパティを使用することでパフォーマンスが向上したことには感謝していprototypeますが、真のプライベートメソッドと変数をミックスに追加しようとすると、かなり面倒になります。一方で、私はこのclosureアプローチが本当に好きですが、パフォーマンスの低下には満足していません。パターンを調べましたmoduleが、かなり冗長であることがわかりました。どこかに幸せな媒体はありますか?

私が苦労していることを説明するために、2つの非常に小さなサンプルクラスを次に示します。

ポイントクラス:

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

// Get the x coordinate.
Point.prototype.getX = function() {
  return this.x;
}

// Get the y coordinate.
Point.prototype.getY = function() {
  return this.y;
}

// Get the (x, y) coordinate.
Point.prototype.getXY = function() {
  return {x: this.x, y: this.y};
}

// Set the x coordinate.
Point.prototype.setX = function(x) {
  this.x = x;
}

// Set the y coordinate.
Point.prototype.setY = function(y) {
  this.y = y;
}

// Set the (x, y) coordinate.
Point.prototype.setXY = function(x, y) {
  this.x = x;
  this.y = y;
}

ユーザークラス:

function User(guid) {
  var guid = guid;

  // Return the user's GUID.
  this.getGuid = function() {
    return guid;    
  }
}

prototype一度に何千ものポイントオブジェクトが使用される可能性があるので、このアプローチが最良の選択肢だと思います。ただし、座標の設定に検証を追加したい場合は、を呼び出すだけでバイパスできますPoint.x = <value>。同様に、私は大部分の時間を呼び出すでしょうPoint.getXY()。それは本質的にパブリックプロパティであるもののために新しいオブジェクトを構築するでしょう。クラスのゲッターとセッターの概念を取り除き、Point完全にオープンなパブリックオブジェクトを作成する必要がありますか?これは、OOPのコンテキストでは間違っているようです。

クラスの場合User、GUIDを内部に格納して、要求できるが変更されないようにします。これは(何かが足りない場合を除いて)このアプローチでは実行できないprototypeため、ある種のを使用せざるを得ませんclosure。一度に数百人のユーザーがアクティブになると予想しているため、パフォーマンスはPointクラスの場合ほど重要ではありません。ただし、コードベース全体で異なるタイプのOOPスタイルを切り替えたくはありません。

それで、一般的な質問として、私が欠けているJSのOOPへのアプローチはありますか?それは私がprototype選択された関数と変数をきれいに民営化しながらプロパティを使用することを可能にしますか?または、私は間違った方向を見ていますか?私はこれに別の方法でアプローチする必要がありますか?

4

4 に答える 4

1

_メソッドを「内部」としてマークするには、ドキュメントとプレフィックスなどの規則のみを使用できますが、javascript にはオブジェクトの実際の強制的なプライベートメンバーはありません。

クロージャーは受け入れられません。特に、このようにクロージャーを使用して「クラス」を拡張したい場合は、「興味深い」結果を持つ可能性のあるオブジェクトではなく、データを所有します。もう 1 つのポイントは、すべての関数オブジェクトを格納するために O(n) メモリを使用することです。これは、ライブラリを非常に簡単に使用できるライブラリのユーザーにとって制御不能である場合、受け入れられません。メモリの問題。

次のように、アンダースコア接頭辞の規則を簡単に使用できます。

function Point(x, y) {
  this._x = x;
  this._y = y;
}

// Get the x coordinate.
Point.prototype.getX = function() {
  return this._x;
}

// Get the y coordinate.
Point.prototype.getY = function() {
  return this._y;
}
于 2012-07-01T21:17:39.507 に答える
0

あなたの経歴はわかりませんが、おそらくおっと、コーヒースクリプトをチェックしてください

于 2012-07-01T17:17:32.193 に答える
0

プロトタイプベースのオブジェクト指向は真のオブジェクト指向ではないため、おそらく間違った場所を見ていると思います。

プロトタイプベースのオブジェクトは、それらがサブクラス化するもののクローンです。したがって、オブジェクトにプロパティ getXY() があると宣言すると、そこから複製されたものに対して広く開かれます。

ですから、本当の問題は、この実装でプライベート関数があなたに何をもたらすと思いますか?

プライベート関数が本当に必要な場合は、クロージャー パターンで処理しなければならない混乱に対処することをお勧めします。

于 2012-07-01T17:35:02.660 に答える
0

開発中にクロージャ アプローチを使用できるため、誰も検証をバイパスしないことがわかり、コードをリリースするときに、より高速なプロトタイプ アプローチに切り替えることができます。

var Release = true;
if (Release) {
    function Point(x, y) {
        this.x = x;
        this.y = y;
    }

    // Get the x coordinate.
    Point.prototype.getX = function () {
        return this.x;
    }

    // Get the y coordinate.
    Point.prototype.getY = function () {
        return this.y;
    }

    // Get the (x, y) coordinate.
    Point.prototype.getXY = function () {
        return {
            x: this.x,
            y: this.y
        };
    }

    // Set the x coordinate.
    Point.prototype.setX = function (x) {
        this.x = x;
    }

    // Set the y coordinate.
    Point.prototype.setY = function (y) {
        this.y = y;
    }

    // Set the (x, y) coordinate.
    Point.prototype.setXY = function (x, y) {
        this.x = x;
        this.y = y;
    }
} else {
    function Point(x, y) {
        var _x = x,
            _y = y;
        return {
            // Get the x coordinate.
            getX: function () {
                return _x;
            },

            // Get the y coordinate.
            getY: function () {
                return _y;
            },

            // Get the (x, y) coordinate.
            getXY: function () {
                return {
                    x: _x,
                    y: _y
                };
            },

            // Set the x coordinate.
            setX: function (x) {
                _x = x;
            },

            // Set the y coordinate.
            setY: function (y) {
                _y = y;
            },

            // Set the (x, y) coordinate.
            setXY: function (x, y) {
                _x = x;
                _y = y;
            }
        }
    }
}
于 2012-07-01T20:59:02.593 に答える