在JavaScript中,我如何创建一个带有可选参数的函数?

38

问题: 在JavaScript中定义带有可选参数的函数的正确方法是什么?

例如:

function myFunc(optionVar1) {
    if(optionVar1 == undefined) {
        ...
    } else {
        ...
    }
}

myFunc('10');  // valid function call
myFunc();      // also a valid function call

在函数声明中使用像Ruby语言一样的问号标记?来表示可选参数,这样做是否合适?

function myFunc(optionVar1?) {...}  //  <--- notice the ? mark

我已经更新了我的答案,但简短的回答是不行,问号不是一个允许在变量名中出现的字符。 - Damovisa
12个回答

72

Javascript中没有明确指定参数是可选的(或必需的)的语法。所有参数都是可选的。如果未指定它们,则它们为undefined,因此您需要检查这一点。例如,此函数实际上将为参数创建默认值10:

function myfunc(someParam) {
  if (someParam === undefined) {
    someParam = 10;
  }
  ...
}

还可以使用arguments属性以编程方式访问参数。

最后,如果您有超过3-4个参数,通常建议改用匿名对象。


8
这段代码可以用ES6语法进行简化:function myfunc(someParam = 10){All the code...}。其中,someParam 参数默认值为 10 - Tim

7

实际上,在JS函数中所有参数都是可选的。如果您省略了参数,不会出现警告或错误。

您可以设置默认值,例如:

function throw_cat(dist){
  dist = typeof dist=='undefined' ? 20 : dist;
   //OR
  dist = dist || 20; //this will assign it to 20 if you pass 0 or another 'falsy' value, though. May be good if you expect a string. String '0' stays, '' or null assigns the default
  //etc...
  }

1
typeof 返回一个字符串。使用 typeof dist==='undefined',或者,我更喜欢的是 dist===undefined - bobince
谢谢,我有点不清楚。在某些情况下(即在函数外部),执行 if(randomvar==undefined) 会产生一个错误 - ReferenceError: randomvar is not defined,所以我使用 typeof。我会添加引号。 - JAL

4

当使用文档注释时,您可以在注释部分中使用注解,例如{Object=}或{number=}:

/** 
 * @param {object=}xyz
 */ 

现代IDE知道如何识别JavaScript的注释,并向您显示有关代码潜在问题的指示。

例子:

/**
 *
 * @param query 
 * @param callback 
 * @param {number=} ttl optional time-to-leave
 */
 loadByJSONP:function loadByJSONP(query, callback, ttl) {
   ...do some work
 }

在这个例子中,'ttl'是可选的。注释{number=}表示该参数是可选的。因此,当您只使用两个参数调用此函数时,您将不会收到警告。
注释也可以用于指定预期类型。这使得您的代码更好,更少出现错误。这是注释的链接:

https://developers.google.com/closure/compiler/docs/js-for-compiler


为什么这对我不起作用?* @param {string=} name optional time-to-leave 我非常需要它能够正常工作。 - tatsu

3

首先,所有编写JavaScript的人,请自己一个忙,阅读《学习高级JavaScript》,作者是John Resig

function myFunc(arg1, arg2 /* varargs... */) {
  var optional = Array.prototype.slice.call( arguments, 2 );

每个函数的参数都是“可选的”,即使你在函数声明的参数列表中声明了它们。

只要充分考虑记录它们。


2
克莱特斯和达莫维莎提出了很好的建议。我还想补充一点,有些人(比如我)可能更喜欢这样的记号:
function foo(/*bar*/) {
   if (arguments.length == 1) {
      var bar = arguments[0];
      ...
   }
}

这有助于向您的代码库的开发人员记录参数是可选的,并记录名称,但它也可以防止在调试器中函数名中显示参数(示例将显示为foo()而不是foo(optional_argument))。否则,使用API的开发人员可能会认为它是必需的。 编辑:这对于旨在在内部使用的可选参数特别有用。

2

2
function connect(hostname, port, method) {
   hostname = hostname || "localhost";
   port = port || 80;
   method = method || "GET";
}

重要网址 Javascript中的可选参数


1
// 1. best way
function sum1(x = 1, y = 2) {
    console.log(x + y)
}
sum1()  // x=1,y=2
sum1(4, 5)  // x=4,y=5
sum1(8)  // x=8,y=2

// 2. Ternary way
function sum2(x) {
    x = x !== undefined ? x : 1; // if x define x=x, if undefine x=1
    console.log(x)
}
sum2(1)
sum2(5)
sum2('foo')
sum2()


// logical way
function sum3(x) {
    x = x || 1;  // x = either x if x is true or 1 if x is not false
    console.log(x)
}
sum3(1)
sum3(5)
sum3('foo')
sum3()

1

只需不定义任何参数并在函数内部访问特殊的参数数组,您就可以在需要可选参数的函数中使用它们。以下是示例。

<HTML>
<HEAD>
<SCRIPT Language="JavaScript">
function foo() {
  var argv = foo.arguments;
  var argc = argv.length;
  for (var i = 0; i < argc; i++) {
    alert("Argument " + i + " = " + argv[i]);
   }
}
</SCRIPT>
</HEAD>
<BODY onload="foo('hello', 'world');">
</BODY>
</HTML>

这并不能帮助人们知道应该包括哪些参数。看起来有点笨拙。 - SeanD

1
在函数声明中使用问号标记(像 Ruby 一样)是否合适?
不,没有语言级别的方法来表示可选参数。但我认为在注释中说明是值得的。
function myFunc(var1, var2 /* optional */, var3 /* optional */) {
    if (var2===undefined) ...

(注意使用三个等号进行精确的相等性测试。否则,传递的null值也将匹配。通常在JS中,您希望使用===进行大多数比较,因为双等号具有不良的弱类型。)

当您拥有不确定数量的可选参数时,通常会从函数语句中省略它们,并且再次注释是礼貌的:

function myFunc(var1 /* , optional var2..varN */) {
    for (var i= 1; i<arguments.length; i++) ...

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