function myFunc(){
arguments = __({requiredArg: undefined, optionalArg: [undefined: 'defaultValue'})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
您还可以使用您希望接收的参数类型替换 undefined ,如下所示:
function myFunc(){
arguments = __({requiredArg: Number, optionalArg: [String: 'defaultValue'})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
125
function foo(requiredArg){
if(arguments.length>1) var optionalArg = arguments[1];
}
function myFunc( requiredA, requiredB, optionalA, optionalB, optionalC ) {
switch (arguments.length - 2) { // 2 is the number of required arguments
case 0: optionalA = 'Some default';
case 1: optionalB = 'Another default';
case 2: optionalC = 'Some other default';
// no breaks between cases: each case implies the next cases are also needed
}
}
function WhoLikesCake(options) {
options = options || {};
var defaultOptions = {
a : options.a || "Huh?",
b : options.b || "I don't like cake."
}
console.log('a: ' + defaultOptions.b + ' - b: ' + defaultOptions.b);
// Do more stuff here ...
}
在JavaScript中,一个遗漏的参数就像一个未初始化的声明变量(只是 var a1; ) . 等于运算符将undefined转换为null,因此这对值类型和对象都很有效,这就是CoffeeScript处理可选参数的方式 .
function overLoad(p1){
alert(p1 == null); // Caution, don't use the strict comparison: === won't work.
alert(typeof p1 === 'undefined');
}
overLoad(); // true, true
overLoad(undefined); // true, true. Yes, undefined is treated as null for equality operator.
overLoad(10); // false, false
function overLoad(p1){
if (p1 == null) p1 = 'default value goes here...';
//...
}
尽管如此,有人担心最好的语义是 typeof variable === 'undefined' 稍好一些 . 我'm not about to defend this since it'是底层API如何实现一个功能的问题;它不应该对API用户感兴趣 .
我还应该补充一点,这里是物理上确保错过任何参数的唯一方法,使用 in 运算符,遗憾的是它不能使用参数名称,因此必须传递 arguments 的索引 .
function foo(a, b) {
// Both a and b will evaluate to undefined when used in an expression
alert(a); // undefined
alert(b); // undefined
alert("0" in arguments); // true
alert("1" in arguments); // false
}
foo (undefined);
/**
* Updates an object's properties with other objects' properties. All
* additional non-falsy arguments will have their properties copied to the
* destination object, in the order given.
*/
function extend(dest) {
for (var i = 1, l = arguments.length; i < l; i++) {
var src = arguments[i]
if (!src) {
continue
}
for (var property in src) {
if (src.hasOwnProperty(property)) {
dest[property] = src[property]
}
}
}
return dest
}
/**
* Inherit another function's prototype without invoking the function.
*/
function inherits(child, parent) {
var F = function() {}
F.prototype = parent.prototype
child.prototype = new F()
child.prototype.constructor = child
return child
}
当使用构造函数函数从一个继承自另一个的对象时,它继承自's easy to accept any arguments which are required by the constructor of the Object you'的构造函数为你做的,如上所述,当 CharField 调用 Field 的构造函数时) .
function usageExemple(a,b,c,d){
//defaults
a=defaultValue(a,1);
b=defaultValue(b,2);
c=defaultValue(c,4);
d=defaultValue(d,8);
var x = a+b+c+d;
return x;
}
只需在全局escope上声明此函数即可 .
function defaultValue(variable,defaultValue){
return(typeof variable!=='undefined')?(variable):(defaultValue);
}
function YourFunction(optionalArguments) {
//var scope = this;
//set the defaults
var _value1 = 'defaultValue1';
var _value2 = 'defaultValue2';
var _value3 = null;
var _value4 = false;
//check the optional arguments if they are set to override defaults...
if (typeof optionalArguments !== 'undefined') {
if (typeof optionalArguments.param1 !== 'undefined')
_value1 = optionalArguments.param1;
if (typeof optionalArguments.param2 !== 'undefined')
_value2 = optionalArguments.param2;
if (typeof optionalArguments.param3 !== 'undefined')
_value3 = optionalArguments.param3;
if (typeof optionalArguments.param4 !== 'undefined')
//use custom parameter validation if needed, in this case for javascript boolean
_value4 = (optionalArguments.param4 === true || optionalArguments.param4 === 'true');
}
console.log('value summary of function call:');
console.log('value1: ' + _value1);
console.log('value2: ' + _value2);
console.log('value3: ' + _value3);
console.log('value4: ' + _value4);
console.log('');
}
//call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
YourFunction({
param1: 'yourGivenValue1',
param2: 'yourGivenValue2',
param3: 'yourGivenValue3',
param4: true,
});
//order is not important
YourFunction({
param4: false,
param1: 'yourGivenValue1',
param2: 'yourGivenValue2',
});
//uses all default values
YourFunction();
//keeps value4 false, because not a valid value is given
YourFunction({
param4: 'not a valid bool'
});
0
如果我错了,请纠正我,但这似乎是最简单的方法(无论如何,对于一个论点):
function myFunction(Required,Optional)
{
if (arguments.length<2) Optional = "Default";
//Your code
}
28 回答
我建议你这样使用ArgueJS:
您还可以使用您希望接收的参数类型替换
undefined
,如下所示:你可以使用一些不同的方案 . 我一直在测试arguments.length:
然后保罗提供了一个失败的场景! - )
理想情况下,您将重构一个对象并使用默认对象传递它,因此传递参数的顺序无关紧要(请参阅下面的答案的第二部分) .
但是,如果您只想要快速,可靠,易于使用且不笨重的东西,请尝试以下方法:
对任意数量的默认参数进行简洁快速修复
它优雅地扩展:每个新默认值的最小额外代码
您可以将其粘贴到任何位置:只需更改所需的参数和变量的数量
如果要将
undefined
传递给具有默认值的参数,这样,该变量将设置为undefined
. 此页面上的大多数其他选项将使用默认值替换undefined
.这是一个为三个可选参数提供默认值的示例(带有两个必需参数)
Simple demo . 这与roenving's answer类似,但可以轻松扩展为任意数量的默认参数,更易于更新,并且using arguments not Function.arguments .
传递和合并对象以获得更大的灵活性
上述代码与许多执行默认参数的方法一样,不能不按顺序传递参数,例如,传递
optionalC
但是让optionalB
回退到默认值 .一个很好的选择是传递对象并与默认对象合并 . 这也有利于可维护性(只需注意保持代码可读,因此未来的合作者不会猜测您传递的对象的可能内容) .
使用jQuery的示例 . 如果你不't use jQuery, you could instead use Underscore' s
_.defaults(object, defaults)
或browse these options:这是a simple example of it in action .
我发现这是最简单,最易读的方式:
Paul Dixon的回答(以我的拙见)不如此可读,但归结为偏好 .
insin的答案要先进得多,但对大功能更有用!
EDIT 11/17/2013 9:33pm: 我为Node.js创建了一个包,使"overload"函数(方法)更容易被称为parametric .
这就是我最终的结果:
这样称呼:
伙计 -
在查看了这些和其他解决方案之后,我尝试使用最初来自W3Schools的一段代码作为基础来解决其中的一些问题 . 您可以找到以下内容 . 每个注释掉的项目都可以正常工作,这样您就可以通过删除单个注释来进行实验 . 需要说明的是,未定义的是“eyecolor”参数 .
在ECMAScript 2015(又名“ES6”)中,您可以在函数声明中声明默认参数值:
更多关于他们的事情this article on MDN(尽管有文章 Headers ,他们在JavaScript中被称为"arguments,"而不是"parameters,") .
目前这是only supported by Firefox,但随着标准的完成,预计支持将迅速提升 .
我习惯于看到处理可选变量的一些基本变化 . 有时,轻松的版本很有用 .
例如,在Backbone.js中广泛使用了与变量
a
一起使用的虚假默认值 .登陆这个问题,搜索 default parameters in EcmaScript 2015 ,因此只提......
使用 ES6 ,我们可以default parameters:
如果您需要查看文字
NULL
,那么您可能会遇到一些问题 . 除此之外,不,我认为你可能走在正确的轨道上 .一些人选择的另一种方法是在参数列表中迭代一组关联变量 . 它看起来有点整洁,但我想它有点(非常小)一点点进程/内存密集 .
我没有't know why @Paul'的回复被低估,但对
null
的验证是一个不错的选择 . 也许一个更肯定的例子会更有意义:在JavaScript中,一个遗漏的参数就像一个未初始化的声明变量(只是
var a1;
) . 等于运算符将undefined转换为null,因此这对值类型和对象都很有效,这就是CoffeeScript处理可选参数的方式 .尽管如此,有人担心最好的语义是
typeof variable === 'undefined'
稍好一些 . 我'm not about to defend this since it'是底层API如何实现一个功能的问题;它不应该对API用户感兴趣 .我还应该补充一点,这里是物理上确保错过任何参数的唯一方法,使用
in
运算符,遗憾的是它不能使用参数名称,因此必须传递arguments
的索引 .Loose type checking
容易写,但
0
,''
,_false
,null
和undefined
将转换为默认值,这可能不是预期的结果 .Strict type checking
更长,但涵盖了大多数情况 . 只有错误地指定默认值的情况才是我们传递
undefined
作为参数 .Checking arguments variable
捕获所有案例,但写起来最笨拙 .
ES6
不幸的是,目前浏览器支持很差
如果传递了OptionalArg,您的逻辑将失败,但计算结果为false - 请尝试将其作为替代方法
或另类成语:
使用最适合您的意图传达最佳意图!
在一个项目中,我注意到我使用可选参数和设置重复了太多,所以我创建了一个处理类型检查的类,并分配一个默认值,从而产生整洁可读的代码 . 请参阅示例,让我知道这是否适合您 .
使用这个类:
未定义的测试是不必要的,并且不像它可能那样健壮,因为正如user568458所指出的,如果传递null或false,则提供的解决方案将失败 . API的用户可能会认为为false或null会强制该方法避免该参数 .
结果是:
最后两个可能是坏的 . 而是尝试:
结果如下:
这不是最佳的唯一情况是当你实际上有可选参数,意味着布尔值或故意空值 .
在OptionalArg为假的所有情况下,您最终会得到defaultValue .
所有上面的日志都是defaultValue,因为所有6都是假的 . 在第4,5,6项情况下,您可能没有兴趣将optionalArg设置为defaultValue,但它设置为因为它们是假的 .
arg || 'default'
是一种很好的方式,适用于90%的情况当您需要传递可能是'falsy'的值时失败
false
0
NaN
""
对于这些情况,您需要更加冗长并检查
undefined
如果你正在使用Underscore库(你应该,它是一个很棒的库):
http://jsfiddle.net/mq60hqrf/
与Oli的答案类似,我使用一个参数Object和一个定义默认值的Object . 带点糖......
......这可以做得更好一些 .
这种方法有什么好处?
你可以省略任意多个参数 - 如果你只想覆盖一个参数的值,你可以只提供那个参数,而不必显式传递
undefined
,比如说有5个参数而你只想自定义最后一个,就像你建议的其他一些方法一样 .当使用构造函数函数从一个继承自另一个的对象时,它继承自's easy to accept any arguments which are required by the constructor of the Object you'的构造函数为你做的,如上所述,当
CharField
调用Field
的构造函数时) .继承层次结构中的子对象可以根据需要自定义其父构造函数的参数,强制执行它们自己的默认值或确保始终使用某个值 .
如果你广泛使用默认值,这似乎更具可读性:
只需在全局escope上声明此函数即可 .
使用模式
fruit = defaultValue(fruit,'Apple');
defaultValue
函数重命名为短名称,只是不要使用default
这是javascript中的保留字 .我尝试了这里提到的一些选项,并对性能进行了测试 . 在这一刻,逻辑似乎是最快的 . 虽然这是随着时间的推移而变化的主题(不同的JavaScript引擎版本) .
这些是我的结果(Microsoft Edge 20.10240.16384.0):
此性能测试可以轻松复制:http://jsperf.com/optional-parameters-typeof-vs-switch/2
这是测试的代码:
这是我的解决方案 . 有了这个,你可以留下你想要的任何参数 . 可选参数的顺序并不重要,您可以添加自定义验证 .
如果我错了,请纠正我,但这似乎是最简单的方法(无论如何,对于一个论点):
使用ES2015 / ES6,您可以利用
Object.assign
,它可以取代$.extend()
或_.defaults()
您也可以使用这样的默认参数
那些比运营商版本更短 .
这似乎是最安全的方式 - 处理所有\ _任何 falsy types 在决定使用 default 之前提供的参数是检查调用函数中是否存在可选参数 .
依赖于参数对象成员创建,如果缺少参数,甚至不会创建参数成员创建,无论它是否被声明,我们可以像这样编写你的函数:
利用这种行为:只要我们需要确保函数在其过程中获得某个值,我们就可以安全地检查参数列表中的任何缺失值 .
在下面的演示代码中,我们将故意将无类型且无值的 undefined 作为默认值,以确定它是否可能在伪造的参数值上失败,例如0 false等,或者它是否按预期运行 .
现在,检查几个有 Value 的参数值,看看它们的存在是否被正确检测到,因此评估为 true :
这意味着 - 他们没有做错 .
正如我们所看到的,参数arg1,arg2,arg3和未声明的arg4正在按顺序返回它们的确切 default 值 . 因为我们现在已经确定它有效,所以我们可以通过使用: if 或三元条件来重写实际上能够使用它们的函数,如第一个例子中所示 .
对于具有多个可选参数的函数, - 循环,可能为我们节省了一些位 . 但是由于参数 names 以编程方式编写了一个默认值,我们只能通过参数[index]来访问它们,这些无用的代码可读性明智 .
但是除了这种在某些编码情况下可能完全可以接受的不便之外,还存在多个和任意数量的参数默认值的另一个无法解决的问题 . 这可能并且应该被视为一个错误,因为我们不能再跳过参数,因为我们曾经可以在不给出值的情况下使用以下语法:
因为它会扔!这使我们无法用我们所需的默认值的特定假类型替换我们的参数 . 这是愚蠢的,因为arguments对象是一个类似于数组的对象,并且应该原生或默认支持这种语法和约定!
由于这个短视的决定,我们不能再希望编写这样的函数:
在这种情况下,我们可以在参数行中编写所需类型的每个默认值,并且至少能够通过args.index访问它们 .
例如,此函数调用将产生:
在我们的默认参数值数组中定义 . 但是仍然可以使用以下内容:
但遗憾的是没有:
否则将记录:
但那是一个更美好的世界!但是 - 对于原始问题 - 最顶层的功能会很好 . 例如 . :
p.s:抱歉在写入时不保留参数输入中所选默认值的类型 .