1

このパターンを使用して、ある種の「コンストラクター」を作成しようとしています。

function mything() {
    var a, b, c;
    ...
    return {
        publicFunc: function() {
            //access private vars here
        }
    };
}

//usage

mything1 = mything();
mything2 = mything();

問題は、私もそれをinstanceofテストに合格させたいということです:

assert(mything1 instanceof mything === true);

これを行う方法はありますか?プロトタイプ関数はプライベート変数にアクセスできないため、通常のコンストラクターを使用しても機能しません。

4

2 に答える 2

4

プライベート変数を持ち、それを instanceof にするためには、わずかに異なるデザイン パターンを使用する必要がありますmything

function mything() {
    var a, b, c;
    ...
    this.publicFunc = function() {
            //access private vars here
        }
    };
}

//usage

var mything1 = new mything();
mything1.publicFunc();
var mything2 = new mything();
于 2013-03-28T23:07:28.027 に答える
1

技術的には可能ですが、問題をよりエレガントに解決できます (説明は以下に続きます)。

function mything() {
  var a, b, c;

  function PrivateConstructor() {
    this.publicFunc = function() {}
  }

  // this is the magic that makes it happen:
  PrivateConstructor.prototype = mything.prototype; 

  return new PrivateConstructor();

}

mything1 = mything();
assert(mything1 instanceof mything); // passes

または、EcmaScript 5 機能を使用すると、次のようになります。

function mything() {
  var a, b, c;

  var object = Object.create(mything.prototype);
  object.publicFunc = function() {}

  return object;
}

mything1 = mything();
assert(mything1 instanceof mything); // passes

説明

instanceof右側のオペランドが関数であり、その関数のプロパティに格納されているオブジェクトが左側のオペランドのプロトタイプ チェーンに含まれている場合、演算子は true を返しprototypeます。

最初の例は、1 つのオブジェクト (プロトタイプ チェーン内)mything.prototypeを生成するためにのみ使用される別の一時的な関数の "prototype" プロパティとして再利用します。2 番目の例では、 を使用して から直接mything.prototype継承することにより、そのようなオブジェクトを作成します。mything.prototypeObject.create()

どちらのオブジェクトも から継承mything.prototypeするため、object instanceof mythingテストに合格します。

そうは言っても、jfriend00 によって提案されたパターンはオーバーヘッドが少なく、必要な機能を提供しながら読みやすくなっています。

于 2013-03-28T23:25:55.137 に答える