0

次のようなオブジェクトがあります。

var myObj = {
  _fooCon: function(f) {
             if (typeof f != 'function') throw new TypeError('Bad Foo');
             this.fn = f;
           },

  _barCon: function(f) {
             if (typeof f != 'function') throw new TypeError('Bad Bar');
             this.fn = f;
           },

  someFoo: function(v) {
             return new this._fooCon(function(x) {
               return x + ' Foo ' + v;
             });
           },

  someBar: function(v) {
             return new this._barCon(function(x) {
               return x + ' Bar ' + v;
             });
           }
};

これを行う理由は、instanceof生産的に使用できるようにするためです(つまり、構造的に同一であるにもかかわらず、異なるシナリオで使用される2つのオブジェクトを区別できます)。someFoo(とsomeBarが類似しているという事実を無視してください!)

コンストラクター関数を抽象化する方法はありますか。たとえば、作成する必要がある場合は、_bazCon繰り返す必要はありません。または、バグがある場合、すべてのコンストラクター定義を修正する必要はありませんか?

私はこのようにファクトリーメンバーを作ってみました:

_factory: function(type, f) {
            if (typeof f != 'function') throw new TypeError('Bad ' + type);
            this.fn = f;
          }

...それから:

_fooCon: function(f) { return new this._factory('Foo', f); }

これを試さなくても、うまくいかないことがわかります!私が探しているものを達成する方法についてのアイデアはありますか?

4

1 に答える 1

2

あなたの関数が本当に同じことをするなら、それはこれと同じくらい簡単です:

var myObj = {
  _factory: function(err) {
                return function(f) {
                    if (typeof f != 'function') throw new TypeError('Bad ' + err);
                    this.fn = f;
                };
            },
  someFoo: function(v) {
             return new this._fooCon(function(x) {
               return x + ' Foo ' + v;
             });
           },

  someBar: function(v) {
             return new this._barCon(function(x) {
               return x + ' Bar ' + v;
             });
           }
};

myObj._fooCon = myObj._factory("Foo");
myObj._barCon = myObj._factory("Bar");

それらを区別する他の動作がある場合_factoryは、コンストラクター内で呼び出される関数の引数を受け取ることができます。その関数は、.callまたはを使用して、構築中のオブジェクトに値を.apply設定できます。this


別のアプローチは、コンストラクターを使用してを作成しmyObj、変数スコープを利用して、コンストラクターを公開する必要がないようにすることです_xxxCon

これは、匿名関数をコンストラクターとして使用します。これは、再度必要ないためです。

var myObj = new function() {
    var _factory = function(err) {
                return function(f) {
                    if (typeof f != 'function') throw new TypeError('Bad ' + err);
                    this.fn = f;
                };
            };

    var _fooCon = _factory("Foo");
    var _barCon = _factory("Bar");

    this.someFoo = function(v) {
             return new _fooCon(function(x) {
               return x + ' Foo ' + v;
             });
           },

    this.someBar = function(v) {
             return new _barCon(function(x) {
               return x + ' Bar ' + v;
             });
           }
};

コンストラクターとして使用する外部関数は必ずしも必要ではありませんが、オブジェクトをに返す関数は必要ですmyObj

関数を公開たい場合は、に変更し、に戻します。_xxxConvarthis.this.someFoosomeBar

于 2013-01-19T18:49:09.857 に答える