JavaScript中跳过可选函数参数

82

请问有没有在JavaScript中跳过可选参数的好方法。

例如,我想要丢弃所有opt_参数:

goog.net.XhrIo.send(url, opt_callback, opt_method, opt_content, {'Cache-Control': 'no-cache'}, opt_timeoutInterval)
4个回答

148

解决方案:

goog.net.XhrIo.send(url, undefined, undefined, undefined, {'Cache-Control': 'no-cache'})

你应该使用undefined来代替要跳过的可选参数,因为这样可以完全模拟JavaScript中可选参数的默认值。

下面是一个小例子:

myfunc(param);

//is equivalent to

myfunc(param, undefined, undefined, undefined);

强烈推荐: 如果你有很多参数,并且在参数列表中可以有可选参数,请使用JSON。看看jQuery是如何实现的。


1
+1. 我不确定这个代码的确切作用(和 undefined 一样吗?),但它似乎最适合“跳过可选参数”。 - Thilo
我发现你永远无法确定在“skipped”参数之外传递什么。未定义?空?0?空字符串?空对象?数组?如果省略参数的行为没有记录,或者没有默认参数,那么你就会陷入麻烦。如果你更新外部库,你就不能安心睡觉了。只有上帝和可能的库开发人员才知道如果你传递任何意外的东西而不是所需的参数会发生什么。通常,如果这种行为没有记录,那么错误就在你身上。 - Dan
这仍然适用于2017年最新的 Google Chrome 版本,所以我投上一票。 - Anonymous
1
嗨,这个很好用,除非函数使用arguments.length。看这个例子:argl = function() { return arguments.length; } argl(1) => 1 argl(1, undefined, undefined) => 3 argl(1, undefined, 2) => 3 - MarekJ47
npm模块oracledb在很大程度上使用arguments.length,主要是为了确定是否提供回调函数。不幸的是,undefined不能用于调用这些方法。需要引入一个if语句来选择正确的参数列表长度wtf - Newlukai

34

简短回答

最保险的选择是undefined,几乎适用于所有情况。虽然如此,你无法欺骗函数被调用时认为你真正省略了一个参数。

如果你因为更短而倾向于使用null,考虑声明一个名为_的变量作为undefined的缩写:

(function() { // First line of every script file
    "use strict";
    var _ = undefined; // For shorthand
    // ...
    aFunction(a, _, c);
    // ...
})(); // Last line of every script

细节

首先需要知道的是:

  • typeof undefined 的结果为 "undefined"
  • typeof null 的结果为 "object"

因此,假设一个函数需要一个值,并且期望它的类型为"number"。如果你提供的值为 null,那么实际上你传递给它的是一个"object"类型,这会导致语义错误。1

随着开发人员不断编写更加强大的 JavaScript 代码,越来越多的函数显式地检查参数的值是否为 undefined,而不是传统的 if (aParam) {...}。如果你因为 nullundefined 都能强制转换为 false 而继续将它们视为可以互换使用的,那么你可能会遇到问题。

但要注意,事实上函数是可以判断一个参数是被省略了(未被传入)还是被设置为 undefined 的:

f(undefined); // Second param omitted
function f(a, b) {
    // Both a and b will evaluate to undefined when used in an expression
    console.log(a); // undefined
    console.log(b); // undefined
    // But...
    console.log("0" in arguments); // true
    console.log("1" in arguments); // false
}

脚注

  1. undefined 虽然也不是 "number" 类型,但它的整个作用就是成为一种不真正存在的类型。这就是为什么它是未初始化变量的默认值,以及函数的默认返回值。

3
通过使用ES6 JavaScript!

function myfunc(x = 1, y = 2, z = 6) {
  console.log(x);
  console.log(y);
  console.log(z);
}
myfunc(5) //Output: 5 2 6
myfunc(3, undefined, 8) //Output: 3 2 8

// Better way!

function myfunc(x = 1, y = 2, z = 6) {
  console.log(x);
  console.log(y);
  console.log(z);
}
// skip y argument using: ...[,] and it's mean to undefine
// 1 argument for ...[,] 2 arguments for ...[,,] and so on.....
myfunc(7, ...[, ], 4); //Output: 7 2 4


...[,] 语法是什么神奇的东西?你介意分享一些文档吗? - Beki
嗨 @Beki,这不是魔法,只是扩展运算符与解构的组合(ES6功能)。 - Mateen

3

只需将参数值设置为null

补充说明:如果您想要传递实际值,则可以跳过最后一个可选参数之后的所有连续可选参数(在这种情况下,您可以完全跳过opt_timeoutInterval参数)。


4
你确定里面没有 === undefined 的检查吗? - Dan
@Dan,你提出的问题是一个通用的JavaScript问题,其中包含了那段代码作为示例。如果你需要关于goog.net.XhrIo.send()如何工作的帮助,请重新表述问题。 - nnnnnn
1
非常感谢@nnnnnn,但这实际上是一个通用的JavaScript问题,答案应该在任何情况下都有效。如果没有通用解决方案,请在您的答案中发布它。 - Dan
1
@Dan,我不能确定实现goog.net.XhrIo.send方法的开发人员如何检查可选参数。他可能会检查param === undefinedtypeof param === "undefined"param === null甚至只是if(param)。但是当您传递null值时,这意味着您意识到此参数是可选的,并明确告诉您不想传递任何有意义的值。 - Yuriy Rozhovetskiy
2
你可以传递undefined而不是null,这样在更多情况下可能会更有效,但我不确定是否有一个答案适用于任何情况。如果我正在编写具有可选参数的函数,我可能会使用== null进行检查以允许undefined或null(除非由于某种原因null是合法值),但我可能会检查arguments对象的长度,我也看到其他代码使用=== null进行检查。 - nnnnnn
一旦null被评估,它可能会导致函数失败,因此应包括“undefined”。 - auerbachb

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接