获取函数参数长度,包括默认参数

时间:2017-03-20 08:42:58

标签: javascript node.js ecmascript-6

如果您使用Function.length属性,则会获得函数所需的参数总数。

但是,根据文档(以及实际尝试),它不包括计数中的默认参数。

  

此数字不包括rest参数,仅包含具有默认值的第一个参数之前的参数   - Function.length

我是否有可能以某种方式得到一个包含默认参数的计数(来自函数外部)?

2 个答案:

答案 0 :(得分:2)

也许你可以自己解析它,比如:

function getNumArguments(func) {
    var s = func.toString();
    var index1 = s.indexOf('(');
    var index2 = s.indexOf(')');
    return s.substr(index1 + 1, index2 - index1 - 1).split(',').length;
}

console.log(getNumArguments(function(param1, param3 = 'test', ...param2) {})); //3

答案 1 :(得分:0)

将我的答案从duplicate question复制到此处:

嗯,这有点混乱,但是我相信这应该可以涵盖大多数边缘情况。

通过将函数转换为字符串并计算逗号,但忽略字符串,函数调用或对象/数组中的逗号来工作。我想不出哪种方案无法返回适当的金额,但是我敢肯定有一种方案,因此这绝不是万无一失的,但在大多数情况下应该可以解决。

更新:已经向我指出,这不适用于getNumArgs(a => {})getNumArgs(function(a){}.bind(null))之类的情况,因此,如果您尝试使用它,请注意这一点。

function getNumArgs(func) {
  var funcStr = func.toString();
  var commaCount = 0;
  var bracketCount = 0;
  var lastParen = 0;
  var inStrSingle = false;
  var inStrDouble = false;
  for (var i = 0; i < funcStr.length; i++) {
    if (['(', '[', '{'].includes(funcStr[i]) && !inStrSingle && !inStrDouble) {
      bracketCount++;
      lastParen = i;
    } else if ([')', ']', '}'].includes(funcStr[i]) && !inStrSingle && !inStrDouble) {
      bracketCount--;
      if (bracketCount < 1) {
        break;
      }
    } else if (funcStr[i] === "'" && !inStrDouble && funcStr[i - 1] !== '\\') {
      inStrSingle = !inStrSingle;
    } else if (funcStr[i] === '"' && !inStrSingle && funcStr[i - 1] !== '\\') {
      inStrDouble = !inStrDouble;
    } else if (funcStr[i] === ',' && bracketCount === 1 && !inStrSingle && !inStrDouble) {
      commaCount++;
    }
  }

  // Handle no arguments (last opening parenthesis to the last closing one is empty)
  if (commaCount === 0 && funcStr.substring(lastParen + 1, i).trim().length === 0) {
    return 0;
  }

  return commaCount + 1;
}

以下是我尝试过的一些测试:https://jsfiddle.net/ekzuvL0c/