3

食べ物、飲み物、スナックなど、javascriptで複数の食べられるクラスがあります。このクラスごとに、異なるパラメーターのセットが必要です。送信される食べられるアイテムのインスタンスを作成する別のファクトリ クラスがあります。

このファクトリを使用して、食べられるアイテムを動的に選択し、引数 (配列形式) を渡す方法を理解できませんか?

私は2つの解決策を考え出しました - 解決策1:

var factory = function(eatable, argumentList){
  var obj = new eatable(argumentList);
  return obj
};

これは問題です。なぜなら、argumentList は配列だからです。

解決策 2

var factory = function(eatable, argumentList){
  var obj =  eatable.apply({}, argumentList);
  return obj
};

これは、食べられるタイプのオブジェクトを実際に作成するわけではありません。

私が本当に望んでいる効果私 は引数リストをjs引数型オブジェクトに変換できるとしましょう -

var obj = new eatable(argumentList.toArguments());
obj instanceOf eatable; // should return true

助けてください!

4

5 に答える 5

4

あ、はい。JavaScript でand を一緒に使用することはできません。newapply同様の質問が以前に尋ねられました: Use of .apply() with 'new' operator. これは可能ですか?

問題は明らかnewです。関数ではなくキーワードです。関数でapplyのみ使用できます。newが a ではなく関数である場合keyword、 と組み合わせて使用​​できますapply

newその方法を理解するために、キーワードとまったく同じことを行う関数を作成してみましょうnew

Function.prototype.new = (function () {
    function Factory(constructor, args) {
        return constructor.apply(this, args);
    }

    return function() {
        Factory.prototype = this.prototype;
        return new Factory(this, arguments);
    };
}());

次のようにコンストラクターを呼び出す代わりに、次のようにします。

var object = new constructor(arg1, ...);

次のようにコンストラクターを呼び出すことができます。

var object = constructor.new(arg1, ...);

そうすることの利点は何ですか?まあ、それは本当に簡単です。はキーワードではなく関数になったため、次のようnewに組み合わせて使用​​できます。apply

var object = Function.new.apply(constructor, [arg1, ...]);

したがって、食べられるファクトリー関数は次のようになります。

var factory = function(eatable, argumentList) {
    var obj = Function.new.apply(eatable, argumentList);
    return obj;
};

編集:ファクトリ関数がすべてeatableコンストラクターを取り、argumentList戻り値を返すだけのnew.apply(eatable, argumentList)場合、Bergi がコメントで指摘したように、factory代わりに次のように定義できます。

var factory = Function.apply.bind(Function.new);

これが役に立ったことを願っています。

于 2013-06-27T14:20:33.203 に答える
1

initオブジェクトを初期化する関数を定義できます。

function Eatable(){

}

Eatable.prototype.init = function(/** arg1, arg2, arg3 **/){
    //  initialize object
}

ファクトリ関数で

var eatable = new Eatable();
eatable.init.apply(eatable, /** pass arguments array here **/);
return eatable;
于 2013-06-27T12:05:54.943 に答える
0

適用するコンテキストを提供する必要があります。コンテキストは、引数を適用しようとしているオブジェクトです。現在渡しているコンテキストは{}Object 型です

var factory = function(eatable, argumentList){
  var obj =  eatable.apply(new Eatable(), argumentList);
  return obj
};

ポリモーフィズムなしではファクトリを使用できないため、オブジェクトを拡張する方法でそれらの食べるものを作成しなかった場合、Eatalbeそれを行うことはできません。

于 2013-06-27T12:02:27.147 に答える
0

これを達成するもう1つの方法は次のとおりです-

var _bind = Function.prototype.bind;
var factory = function(_constructor, _argumentList){
  var obj = _bind.apply(_constructor, [null].concat(_argumentList));
  return obj
};
于 2014-07-22T10:41:57.497 に答える