2

JavaScriptで次のように動作させる方法はありますか?

var orders = [
   {milk: true, sugar: "extra"}, 
   {milk: false, sugar: "normal"}
   ];

function makeCoffee(sugar, milk) {
    console.log(sugar);
    console.log(milk);
}

orders.forEach(makeCoffee);
4

3 に答える 3

2

コメントで述べたようにfunc.toString()、関数 †</sup> のソースを返すブラウザーでは、署名を解析してパラメーター名を抽出できます。

var arg_names = makeCoffee.toString()
            .match(/function[^(]*\(([^)]*)\)/)[1].split(', ');

orders.each(function(order) {
    makeCoffee.apply(null, arg_names.map(function(name) {
        return order[name];
    });
});

JavaScript はリフレクション API を提供しないため、おそらくこれが唯一の方法です。


コードがサポートされているブラウザーを明示的に指定しない場合、これは機能しない可能性があります (IE が何を返すかはわかりませんfunc.toString)。オブジェクトを引数として渡すことをお勧めします。


†: ただし、関数の正確な表現は実装に依存します。仕様からの対応する説明は次のとおりです。

関数の実装依存の表現が返されます。この表現には、a の構文がありますFunctionDeclaration。特に、表現文字列内の空白、行末記号、およびセミコロンの使用と配置は実装に依存することに注意してください。

于 2012-07-31T09:29:38.283 に答える
0

私が今まで思いつくことができる最高のものは次のとおりです。

function makeCoffee() {
    console.log(this.milk);
    console.log(this.sugar);
}

orders.forEach(function(x) {makeCoffee.call(x)})

長所:

  • 作品

短所(IMO):

  • これにより、orderとmakeCoffeeの間に不要な結合が導入されます(構成と継承の関係がどのようにパンアウトされたかのようなものです)。
  • 入力を宣言するmakeCoffee関数の明示性が失われます
于 2012-07-31T09:13:32.080 に答える
0

これをお勧めします:

//Should go to config.js
var COFFEE_SUGAR_DEFAULT="normal";

var orders = [
   {milk: true, sugar: "extra"}, 
   {milk: false, sugar: "normal"}
   ];

function makeCoffee(coffeeDefinition) {
    if (!coffeeDefinition.sugar) coffeeDefinition.sugar=COFFEE_SUGAR_DEFAULT;
    if (!coffeeDefinition.milk) coffeeDefinition.milk=false; //might not be a real boolean
    console.log(coffeeDefinition.sugar);
    console.log(coffeeDefinition.milk);
}

orders.forEach(function(x) {makeCoffee(x)})

長所:

  • 動作し、堅牢です
  • 必要なカップリングのみを導入
  • たとえば、拡張可能です"decaffeinated":false

短所:

  • かわいくない
于 2012-07-31T09:24:11.503 に答える