如何从具有不同参数签名的函数中解析参数值?

问题描述 投票:0回答:4

我有一个名为“Time”的函数,它接受 0 到 6 个参数。

function Time(year,month,day,hour,minutes,options) {

}

如果没有定义前一个参数,则无法定义月、日、时、分参数。

即使“options”参数是可选的,如果存在,它也必须是最后一个参数。

但是,用户只能定义年份和月份,然后是选项。

如何避免用户必须这样写:

var newTimeInstance = Time(2024,06, undefined, undefined, undefined, options {
   fr: {
     // ...
   },
   es: {
     // ...
   }
})

如果不可能,是否有其他方法将选项连接到函数?

我已经尝试过:

var newTimeInstance = Time(2024,01).options({ ... })
但是我无法访问newTimeInstance中的其他构造函数。

javascript function parsing arguments variadic
4个回答
2
投票

不方便,但你可以这样做:

function Time(...args) {
  if (args.length === 3) {
    const [year, month, options] = args
    console.log({
      year,
      month,
      options
    })
  }
  // other cases
}

Time(2024, 4, {
  extra: 'options'
})


0
投票

使用

Array::reduceRight()
检查
arguments

function Time(year,month,day,hour,minutes,options) {
  [...arguments].reduceRight((r, arg, idx, arr) => {
    if(arg === undefined && arr[idx + 1] !== undefined) throw new Error('An argument cannot be undefined');
  });
}

Time(2024, 3, undefined); // ok
Time(undefined, 2); // an error


0
投票

如何使用一种由 utiliy/helper 函数覆盖的自定义参数解析方法,其中一个附加的,在更详细的范围内,将决定参数签名是否有效以及是否清理某些值或抛出错误......

function isObjectObject(value) {
  return (/^\[object\s+Object\]$/).test(
    Object.prototype.toString.call(value)
  );
}

function parseArgumentsSignature(args) {
  const params = [];
  let options;
  let error;

  args
    .slice(0, 6)

    // every allows an early exit while using a callback function.
    .every((value, idx) => {
      let proceed = true;

      if (isObjectObject(value)) {

        options = value;
        proceed = false;

      } else if (value == null) {

        params[idx] = undefined;
      } else {
        value = parseInt(value, 10);
        if (Number.isFinite(value)) {

          params[idx] = value;
        } else {
          error = new TypeError('Invalid arguments signature.');

          proceed = false;
        }
      }
      return proceed;
    });

  return (error && {
    error,
  } || {
    params, 
    ...(options && { options } || {}),
  });
}

function Time(...args/* year, month, day, hour, minutes, options */) {
  const parsed = parseArgumentsSignature(args);

  if (Object.hasOwn(parsed, 'error')) {
    throw parsed.error;
  }
  const {
    params: [
      year = 0, month = 0, day = 0, hour = 0, minutes = 0,
    ],
    options = null,
  } =
    parsed;

  console.log({
    year, month, day, hour, minutes, options, params: parsed.params,
  });
}

console.log(
  "Time(...[2024, 06,,, null, null, { fr: 'fr', es: 'es' }]);"
);
Time(...[2024, 06,,, null, null, { fr: 'fr', es: 'es' }]);

console.log(
  "Time(...[2024, 06,,,, { fr: 'fr', es: 'es' }]);"
);
Time(...[2024, 06,,,, { fr: 'fr', es: 'es' }]);

console.log(
  "Time(2024, { fr: 'fr', es: 'es' });"
);
Time(2024, { fr: 'fr', es: 'es' });

console.log(
  "Time(2024, 06);"
);
Time(2024, 06);

console.log(
  "Time(2024, 'foo bar');"
);
Time(2024, 'foo bar');
.as-console-wrapper { min-height: 100%!important; top: 0; }


0
投票

为具有默认空值的参数创建一个对象(

{param1, param2, ..., paramx} = {}
,又名解构分配)。

这样你就永远拥有命名变量。调用函数需要更多的输入,但它提供了更好的(命名)参数处理, 灵活性(例如,您可以添加参数而无需破坏/不必重构对函数的现有调用),用户只需提供所需的参数,不需要以固定的顺序提供它们。

看起来像:

function Time({year,month,day,hour,minutes,options = `dst:0`} = {}) {
  console.log(`your input: ${year ? `year: ${year}` : ``}${
    month ? `, month: ${month}` : ``}${
    day ? `, day: ${day}` : ``}${
    hour ? `, hour: ${hour}` : ``}${
    minutes ? `, minutes: ${minutes}` : ``} (options: ${options})`);
}

Time();
Time({year: 2024, hour: 12, options: `dst:1`});
Time(`this is not available`);
Time({year: 2024, month: 0, day: 21, hour: 12, minutes: 30,});

const now = new Date();
const params = {
  year: now.getFullYear(),
  month: now.getMonth(),
  day: now.getDate(),
  hour: now.getHours(),
  minutes: now.getMinutes(),
  options: `dst:1`
};
Time(params);
.as-console-wrapper {
    max-height: 100% !important;
}

© www.soinside.com 2019 - 2024. All rights reserved.