3

いくつかの関数とメンバー オブジェクトを含む Javascript クラスがあります。

function MyUtils()
{
  // Member Variables (Constructor)
  var x = getComplexData();
  var y = doSomeInitialization();

  // Objects
  this.ParamHash = function()
  {
    // Member variables
    this.length = 0;
    this.items = new Array();

    // Constructor
    for (var i = 0; i < arguments.length; i += 2)
    {
      // Fill the items array.
      this.items[arguments[i]] = arguments[i+1];
      this.length++;
    }
  }

  // Functions
  this.doSomething = function()
  {
    // Do something.
    // Uses the items in the ParamHash object.
    for (var i in this.ParamHash.items)
    {
      // Really do something!
    }

    // Clear the ParamHash object -- How??
  }
}

これは、次の方法で呼び出されます。

// First call - works fine.
var utils = new MyUtils();
utils.paramHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();

// Don't want to re-initialize.
// utils = new MyUtils();

// Consequent call - crashes ["Object doesn't support this action."].
utils.paramHash = new utils.ParamHash("c", 3);
utils.doSomething();

utils問題は、再初期化せずにコード全体で同じオブジェクトを再利用したいという制限から発生します。また、呼び出すたびに ParamHash オブジェクトを最初から再作成する必要があります。ただし、その後 ParamHash コンストラクターを呼び出すと、「オブジェクトはこのアクションをサポートしていません」というエラーがスローされます。この段階で、utils.paramHash オブジェクトにはまだ古い値 (「a」、「b」) が含まれていることがわかります。

アイテムと長さをnullに設定する、配列からアイテムをポップするなど、ParamHashオブジェクトをクリアするさまざまな方法を試しました。次の方法を使用するまで(関数内で)何も機能しないようでしたdoSomething()

this.paramHash.items = new Array();
this.paramHash.length = 0;

これは間違っているように思えます。メンバー変数が多数ある場合はどうすればよいでしょうか...それぞれを個別にリセットする必要がありますか? 問題は、ParamHashオブジェクトを初期状態にリセットする最善の方法は何かということです。よりクリーンで直接的な方法があることを願っています。何かのようなもの :

// Doesn't work! :-(
this.paramHash = new function() {};

編集: クロスブラウザー ソリューションを探しています - 少なくとも IE6+ および FF 2+ で動作するもの。


解決策:クリストフのおかげで、関数MyUtilsのインスタンスのみを保持する別の変数/プロパティを作成することでそれを行うことができました。ParamHash

function MyUtils()
{
  // Same ol' stuff.
  var myParamHash;
}

// First call - works fine.
var utils = new MyUtils();
utils.myParamHash = new utils.ParamHash("a", 1, "b", 2);
utils.doSomething();

// Consequent call - works fine now.
utils.myParamHash = new utils.ParamHash("c", 3);
utils.doSomething();
4

3 に答える 3

3

これ

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

ParamHash()コンストラクター関数を保持するプロパティをインスタンスオブジェクトで上書きします。コンストラクターを元に戻すことができます

utils.ParamHash.constructor

しかし、よりクリーンな方法は、そもそもそれを上書きせず、インスタンスを保持するために別のプロパティを使用することです。


セレブラスが解決しようとしている正確な問題はわからないので、彼がやっていることには正当な理由があるかもしれません。しかし、私の意見では、彼の解決策は非常に複雑です。私はこのようなことをします:

function MyUtils() {
    this.x = getComplexData();
    this.y = doSomeInitialization();
    this.params = {};
}

MyUtils.prototype.doSomething = function() {
    for(var prop in this.params) {
        if(this.params.hasOwnProperty(prop)) {
            // do stuff
        }
    }
};

var utils = new MyUtils;
utils.params = { a : 1, b : 2 };
utils.doSomething();

hasOwnProperty()誰もが混乱していないことを確認できる場合は、のチェックは不要ですObject.prototype


いくつかの追加コメント:

  • JavaScriptでは、通常、コンストラクター関数の名前のみが大文字になります
  • items配列ではなく、プレーンオブジェクト、つまりthis.items = {};
于 2009-02-26T17:57:24.927 に答える
2

あなたがこれをしたとき

utils.ParamHash = new utils.ParamHash("a", 1, "b", 2);

ParamHashコンストラクター関数をオブジェクトインスタンスに置き換えました。new ParamHash()utils.ParamHashはコンストラクター関数ではなくなったため、後続は失敗します。

これを試して:

var utils = new MyUtils();
utils.paramHashInstance = new utils.ParamHash("a", 1, "b", 2);
utils.DoSomething();
于 2009-02-26T17:57:36.453 に答える