Javascript 处理可选参数的节点模块

Javascript 处理可选参数的节点模块,javascript,node.js,npm,Javascript,Node.js,Npm,我正在寻找一个Node.js模块,它可以处理和分配可选参数 例如,假设我有这个函数签名: function foo(desc, opts, cb, extra, writable) { “desc”和“cb”是必需的,其他都是可选的;这是一段内部代码,不是公共API的一部分,但我仍然需要一种方法来正确处理它。在代码库中编写逻辑来处理这些类型的情况变得越来越棘手 有人知道一个好的NPM模块可以处理这种事情吗?找不到 我不相信默认参数可以解决这个问题 例如: const args = ['desc

我正在寻找一个Node.js模块,它可以处理和分配可选参数

例如,假设我有这个函数签名:

function foo(desc, opts, cb, extra, writable) {
“desc”和“cb”是必需的,其他都是可选的;这是一段内部代码,不是公共API的一部分,但我仍然需要一种方法来正确处理它。在代码库中编写逻辑来处理这些类型的情况变得越来越棘手

有人知道一个好的NPM模块可以处理这种事情吗?找不到

我不相信默认参数可以解决这个问题

例如:

const args = ['description', function(){}, []];

foo.apply(global,args);
如果我有

function foo(desc, opts = {}, cb, extra, writable){}
然后opts将采用函数的值,而不是默认的{}值

对吧??还是错了

我现在就是这样解决的:

foo: function foo(desc, opts, cb, extra, writable) {

            if (typeof desc !== 'string') {
                SumanErrors.badArgs(suman, true, new Error('Need a description for the test suite.'));
            }
            else if (typeof opts === 'function') {

                writable = extra;
                extra = cb;
                cb = opts;
                opts = {};

            }
            else {
                if (typeof desc !== 'string') {
                    SumanErrors.badArgs(suman, true, new Error('desc is not a string'));
                }
                if (typeof opts !== 'object') {
                    SumanErrors.badArgs(suman, true, new Error('opts is not an object'));
                }
                if (typeof cb !== 'function') {
                    SumanErrors.badArgs(suman, true, new Error('cb is not a function'));
                }
            }

            return {
                desc: desc,
                opts: opts,
                cb: cb,
                extra: extra,
                writable: writable
            }
        }

只要函数签名符合某些规则,就可以编写一个NPM模块来处理这类事情。上面的内容看起来并没有那么糟糕,但可能会变得更加棘手。

我不太理解是否需要
npm
模块——如果您使用的是ES2015,您可以在方法声明中分配默认参数(请参阅)。

在Javascript中,参数和参数完全根据其位置确定

function test(a, b, c) {
  console.log(a); // 1
  console.log(b); // 2
  console.log(c); // 3
}
test(1, 2, 3);
也就是说,没有办法做到这一点:

function test(a, b, c) {
  b = defaultValue(b); // Assign some default value to b
  console.log(a); // 1
  console.log(b); // 'Default'
  console.log(c); // 2
}
test(1, 2);
语言的语义不允许它,句号。您可以选择更改参数的顺序。如果您将所有必需的参数放在第一位,最后一个参数是可选的,那么它将按预期工作

function test(a, b, c) {
  c = defaultValue(c); // Assign some default value to c
  console.log(a); // 1
  console.log(b); // 2
  console.log(c); // 'Default'
}
test(1, 2);
这适用于任意数量的可选参数

function test(a, b, c, d, e, f, g, h, i) {
  c = defaultValue(c);
  ...
  i = defaultValue(i);
  console.log(a); // 1
  console.log(b); // 2
  console.log(c); // 'Default'
  ...
  console.log(i); // 'Default'
}
test(1, 2);
如果不想重新排列参数的顺序,可以通过传递对象来创建伪命名参数

function test(opts) {
  fillInDefaults(opts);
  console.log(opts.a); // 1
  console.log(opts.b); // 'Default'
  console.log(opts.c); // 2
  console.log(opts.d); // 'Default'
}
test({
  a: 1,
  c: 2
});

我正在研究解决此问题的通用解决方案:

如果有人知道有人已经尝试过这样做,请告诉我。在我不太彻底的搜索中,我什么也没找到

“语用”允许您定义必需参数和可选参数、可选参数的默认值,并根据您定义的规则将这些值放置在参数列表中的正确位置

实际上,对于在公共/私有API中接受varargs的函数数量有限的情况,值得进行额外的配置,以避免编写自己的代码来完成正确解析或有参数的繁琐、容易出错的任务


(此库的使用是通过对数组的分配进行分解而实现的;否则使用会有点不方便)

“要求我们推荐或查找书籍、工具、软件库、教程或其他非现场资源的问题对于堆栈溢出来说是离题的,因为它们往往会吸引自以为是的答案和垃圾邮件。相反,请描述问题以及迄今为止为解决问题所做的工作。“此外,如果传递
--harmony\u default\u parameters
标志,则可以使用。可以将desc和cb作为前两个参数。最后,没有一个模块能够解决这个问题。要传递
cb
值,您需要传递
opts
的内容,即使您刚刚传递了
未定义的
。JS无法知道您的意思是将第二个值作为第三个参数传递。您可以重写函数以获取允许您使用“命名”参数的对象;但除此之外,是的,你是正确的。@AlexMills,无论是什么类型,都是顺序。看我的答案。我不认为默认参数可以解决这个问题,我会尝试解释原因。可能是错误的。如果您没有先设置所需的参数,那么是的,您是对的。我会改变参数的顺序,这样任何“可选的”都会在末尾。或者,我会使用单个对象作为参数——这样,对象上的每个键都是可选的,而不会破坏参数的数量(及其顺序)。是的,但并不总是那么简单。基本上,我在上面所做的是构造一个选项对象。在此之前构造一个options对象实际上是同一个问题,如果这有意义的话:)问题是如果函数签名的末尾有两个或更多可选参数,我们就有同样的问题要解决!类似地,在将参数传递给函数之前构造一个options对象实际上为我们提供了同样需要解决的问题,正如我向Arthur Kay提到的那样。希望这是有意义的:)@AlexMills如果有两个或更多可选参数,就没有问题。您可以调用
test(1,2)
,并且
test
可以(理论上)在最后获取无限多个可选参数,并且它可以正常工作。事先构造一个options对象并不会带来任何问题,除非您从外部源获得数组中的参数,而没有关于这些参数要传递给您的信息。