2012-02-10 11 views
0

引数をパラメータに簡単にマップできるJavaScriptモジュールがありますか?ここで私はそれが動作想像する方法である:オプション/デフォルトパラメータの軽量JavaScriptモジュール

VAR引数= assignArguments(引数、 'P1'、 'P2'、[{ 'P3':0}、 'P4']、{ 'P5': '未知の'});

関数内では、引数を引数に関連付けたオブジェクトを生成するために関数を呼び出します。配列またはインラインオブジェクト内で定義されたパラメータはオプションであると見なされ、インラインオブジェクトではデフォルト値の割り当てが許可されます。その他のパラメータはすべて「必須」とみなされます。私はこのようなライブラリがすでに存在している期待しています

foo(1): { p1: 1, p3: 0, p5: 'unknown' } // no p2 (aka undefined) 
foo(1, 2): { p1: 1, p2: 2, p3: 0, p5: 'unknown' } 
foo(1, 2, 3): { p1: 1, p2: 2, p3: 0, p4: 3, p5: 'unknown' } 
foo(1, 2, 3, 4): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 'unknown' } 
foo(1, 2, 3, 4, 5): { p1: 1, p2: 2, p3: 3, p4: 4, p5: 5 } 

は、ここではいくつかのサンプルの入力/ outpusです。この論理はたくさん繰り返され、私は可能な限り削除したい。

誰もがこのようなライブラリを認識していますか?もしそうでなければ、誰かが私を1つの実装のための正しい道に送りつけることができますか?

+1

私はこれを実装したcoffeescriptを使用します。 – akonsu

答えて

0

私は先に進んで、これを自分自身で行う方法を考えました。これは、文字列、配列、およびオブジェクトで構成されたオブジェクトグラフの解析です。かなり長いですが、うまくいきます。

function assignArguments(values, expression) {    
    // determine how many arguments are needed for each parameter 
    // grab all of the defaults, too 
    var needed = 1; 
    var argsNeeded = {}; 
    var defaults = {}; 
    var queue = [expression];    
    for (var queueIndex = 0; queueIndex < queue.length; ++queueIndex) { 
     var node = queue[queueIndex]; 
     if (typeof node === 'string') { 
      // the node is a required parameter 
      argsNeeded[node] = needed; 
      ++needed; 
     } else if (node instanceof Array) { 
      // the node is a list of parameters 
      for (var index = 0; index !== node.length; ++index) { 
       queue.push(node[index]); 
      } 
     } else { 
      // the node is a list of optional parameters with defaults 
      // make sure there isn't more than one parameter 
      var count = 0; 
      for (var key in node) { 
       if (node.hasOwnProperty(key)) { 
        if (count !== 0) { 
         throw new Error('A default parameter list had more than one value.'); 
        } 
        defaults[key] = node[key]; 
        queue.push(key); 
        ++count; 
       } 
      } 
     } 
    } 

    // determine the order that the parameters appear 
    var parameters = []; 
    var stack = [expression]; 
    while (stack.length > 0) { 
     var node = stack.pop(); 
     if (typeof node === 'string') { 
      // the node is a required parameter 
      parameters.push(node); 
     } else if (node instanceof Array) { 
      // the node is a list of parameters 
      var index = node.length; 
      while (index !== 0) { 
       --index; 
       stack.push(node[index]); 
      } 
     } else { 
      // the node is an optional parameter with defaults 
      // we'll check for multiple parameters 
      var count = 0; 
      for (var key in node) { 
       if (node.hasOwnProperty(key)) { 
        if (count > 0) { 
         throw new Error('A default parameter list had more than one value.'); 
        } 
        stack.push(key); 
        ++count; 
       } 
      } 
     } 
    } 

    var result = {}; 
    var valueIndex = 0; 
    for (var index = 0; index !== parameters.length; ++index) { 
     var parameter = parameters[index]; 
     var needed = argsNeeded[parameter]; 
     if (needed > values.length) { 
      if (parameter in defaults) { 
       result[parameter] = defaults[parameter]; 
      } 
     } else { 
      result[parameter] = values[valueIndex]; 
      ++valueIndex; 
     } 
    } 

    return result; 
} 

これを使用した例を示します。

function foo() { 
    var params = assignArguments(arguments, ['p1', 'p2', [{p3:0}, 'p4'], {p5: 'unknown'}]); 
    return params; 
} 

console.log(foo(1)); 
console.log(foo(1, 2)); 
console.log(foo(1, 2, 3)); 
console.log(foo(1, 2, 3, 4)); 
console.log(foo(1, 2, 3, 4, 5));