4

私はやや大規模な JS アプリケーションに取り組んでおり、いくつかの一般的な機能をユーティリティ クラスに分割したいと考えています。しかし、私はそれをどのように進めるべきかについてははっきりしていません。

たとえば、ユーティリティ クラスで関数を呼び出す必要がある多数の形状ベースのクラスがあるとします。

// Triangle class
Triangle.prototype = new Shape();
Triangle.prototype.constructor = Triangle;

function Triangle() {...}
Triangle.prototype.drawOutline = function() {
  var outline = Utility.canvas.trace(this._canvas); // Trace the shape.
  this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

// Circle class
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;

function Circle() {...}
Circle.prototype.drawOutline = function() {
  var outline = Utility.canvas.trace(this._canvas); // Trace the shape.
  this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

Utilityグローバルレベルでクラスをインスタンス化することは理にかなっていますか? その上に追加のレベルが必要だと思いApplicationます。たとえば、、、などです。残念ながら、この方法では、各特殊化された形状クラスは、より大きなプログラム構造が何であるかを知る必要があり (したがって、 を参照できます)、あまり良くありません。Application.UtilityApplication.UIApplication.Utility

継承されていない一般化されたクラス関数を特殊化された JS クラスに使用させるための、より適切で好ましい方法はありますか?


編集:これを C++ または Javaの#includeorステートメントに関連付けようとしていると言うのが役立つかもしれません。importJSでこれを行う最良の方法は何ですか?

4

4 に答える 4

3

すべてのコードを匿名関数でラップしていると仮定すると、私が通常行うことは、オブジェクト (名前空間) を作成し、そこにすべてのユーティリティを配置することです。

;(function(){

  var Utils = {
    triangle: function () { ... },
    circle: function () { ... }
  }

}())

次に、それを使用するときはいつでも、いつユーティリティを使用してUtils.circle(...)いるかを知ることができ、それらを追跡したり、新しいものを追加したりするのは簡単です.

これを C++ または Java の #include または import ステートメントに関連付けようとしていると言うことは助けになるかもしれません。JSでこれを行う最良の方法は何ですか?

この場合、最も簡単な方法は、concat.shファイルなどを作成し、その間にすべてを追加することですstart.jsend.js

start.js

;(function(){

ユーティリティ.js

var Utils = {
  triangle: function () { ... },
  circle: function () { ... }
}

end.js

}())

concat.sh

もちろん、順序は重要です。

#!bin/bash
cat start.js utils.js end.js > out.js

node.js に興味がある場合は、わずかな構成でこれらすべてを実行するgruntを確認してください。

それ以外の場合、より高度なものには CommonJS モジュールを使用してください。

于 2012-07-03T00:26:20.707 に答える
1

問題は、実際にはユーティリティクラスであり、実際にはユーティリティクラスであってはならないということかもしれません。たぶん、次のようなことをするのが最善です:

// Triangle class
Triangle.prototype = new Shape();
Triangle.prototype.constructor = Triangle;

function Triangle() {...}
Triangle.prototype.drawOutline = function() {
}

// Circle class
Circle.prototype = new Shape();
Circle.prototype.constructor = Circle;

function Circle() {...}
Circle.prototype.drawOutline = function() {
}

function OutlineDrawer(shape)
{
    this.shape = shape;
}

OutlineDrawer.prototype.draw(viewport)
{
    var outline = Utility.canvas.traceShape(this.shape.canvas()); // Trace the shape.
    viewport.drawImage(outline, 0, 0); // Draw the traced outline.
}

あなたは形に多くの責任を負っています。シェイプは、シェイプの特定のインスタンスのプロパティを定義する必要がありますが、おそらく別のクラスを使用してそれらをトレースする必要があります。同じ形状を異なるビューポートに描画する(たとえば、ファイルに保存するため)か、異なるアルゴリズムを使用して同じシーンを描画する(速度、パフォーマンス、品質を調整する)ことができます。等...

于 2012-07-03T00:39:31.633 に答える
1

名前空間を設定する最大の理由は、ライブラリ間の衝突を避けるためです。個人的には、私が書いたものすべてにプレフィックス dt を付けています。だから私は dt.Utility を持っているでしょう。プレフィックスを選択して、それを使用します。=)

于 2012-07-03T00:21:44.093 に答える
0

他の方と同じ回答です。

プロトタイプをグローバル オブジェクト内に配置します (あまりお勧めしませんが、特殊なケースです)。


// Utils.js

// treat this global object as a "namespace" or "module"
var Utils = 
{

  // Triangle class
  Triangle.prototype = new Shape();
  Triangle.prototype.constructor = Triangle;

  function Triangle() {...}
    Triangle.prototype.drawOutline = function() {
    var outline = Utility.canvas.traceShape(this._canvas); // Trace the shape.
    this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
  }

  // Circle class
  Circle.prototype = new Shape();
  Circle.prototype.constructor = Circle;

  function Circle() {...}
    Circle.prototype.drawOutline = function() {
    var outline = Utility.canvas.traceShape(this._canvas); // Trace the shape.
    this._viewport.drawImage(outline, 0, 0); // Draw the traced outline.
  }
} // var Utils

// anotherfile.js

var MyTriangle = new Utils.Triangle();
var MyCircle  =  new Utils.Triangle();

このトリックは、「モジュール ソフトウェア デザイン パターン」と呼ばれます。

于 2012-07-03T00:54:49.683 に答える