我总是在JavaScript中处理可选参数,如下所示:
function myFunc(requiredArg, optionalArg){ optionalArg = optionalArg || 'defaultValue'; // Do stuff }
有没有更好的方法呢?
是否有任何使用||
这种情况会失败的情况?
如果传递了OptionalArg,您的逻辑将失败,但评估为false - 请尝试将此作为替代方法
if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
或另类成语:
optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
使用哪个成语最能传达您的意图!
在ECMAScript 2015(又名"ES6")中,您可以在函数声明中声明默认参数值:
function myFunc(requiredArg, optionalArg = 'defaultValue') { // do stuff }
在这篇关于MDN的文章中更多关于它们(尽管文章标题,它们在JavaScript中被称为"参数"而不是"参数").
目前仅支持Firefox,但随着标准的完成,预计支持将迅速提升.
我发现这是最简单,最易读的方式:
if (typeof myVariable === 'undefined') { myVariable = 'default'; } //use myVariable here
Paul Dixon的回答(以我的拙见)不如此可读,但归结为偏好.
insin的答案要先进得多,但对大功能更有用!
编辑11/17/2013 9:33 pm:我已经为Node.js创建了一个包,它可以更容易地"重载"称为参数的函数(方法).
如果您需要查看文字NULL
,那么您可能会遇到一些问题.除此之外,不,我认为你可能走在正确的轨道上.
一些人选择的另一种方法是在参数列表中迭代一组关联变量.它看起来有点整洁,但我想它有点(很少)更多的进程/内存密集.
function myFunction (argArray) { var defaults = { 'arg1' : "value 1", 'arg2' : "value 2", 'arg3' : "value 3", 'arg4' : "value 4" } for(var i in defaults) if(typeof argArray[i] == "undefined") argArray[i] = defaults[i]; // ... }
理想情况下,您将重构传递对象并将其与默认对象合并,因此传递参数的顺序无关紧要(请参阅下面的答案的第二部分).
但是,如果您只是想要快速,可靠,易于使用且不笨重的东西,请尝试以下方法:
它优雅地扩展:每个新默认值的最小额外代码
您可以将其粘贴到任何位置:只需更改所需的参数和变量的数量
如果要传递undefined
具有默认值的参数,则以此方式将变量设置为undefined
.此页面上的大多数其他选项将替换undefined
为默认值.
这是一个为三个可选参数提供默认值的示例(带有两个必需参数)
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 } }
简单的演示.这类似于 roenving的答案,但可以轻松扩展为任意数量的默认参数,更容易更新,并且不使用arguments
Function.arguments
.
与许多做默认参数的方法一样,上面的代码不能不按顺序传递参数,例如,传递optionalC
但是optionalB
要退回到默认值.
一个很好的选择是传递对象并与默认对象合并.这也有利于可维护性(只需注意保持代码可读性,因此未来的合作者不会猜测您传递的对象的可能内容).
使用jQuery的示例.如果你不使用jQuery,你可以使用Underscore _.defaults(object, defaults)
或浏览这些选项:
function myFunc( args ) { var defaults = { optionalA: 'Some default', optionalB: 'Another default', optionalC: 'Some other default' }; args = $.extend({}, defaults, args); }
这是一个简单的例子.
你可以使用一些不同的方案.我一直在测试arguments.length:
function myFunc(requiredArg, optionalArg){ optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg; ...
- 这样做,它不可能失败,但我不知道你的方式是否有任何失败的机会,只是现在我想不出一个场景,它实际上会失败...
然后保罗提供了一个失败的场景! - )
与Oli的答案类似,我使用一个参数Object和一个定义默认值的Object.带点糖......
/** * 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 }
......这可以做得更好一些.
function Field(kwargs) { kwargs = extend({ required: true, widget: null, label: null, initial: null, helpText: null, errorMessages: null }, kwargs) this.required = kwargs.required this.label = kwargs.label this.initial = kwargs.initial // ...and so on... } function CharField(kwargs) { kwargs = extend({ maxLength: null, minLength: null }, kwargs) this.maxLength = kwargs.maxLength this.minLength = kwargs.minLength Field.call(this, kwargs) } inherits(CharField, Field)
这种方法有什么好处?
您可以省略任意数量的参数 - 如果您只想覆盖一个参数的值,您可以只提供该参数,而不必显式传递undefined
,比如说有5个参数而您只想自定义最后一个参数一,就像你建议的其他一些方法一样.
当使用构造函数函数从一个继承自另一个的对象时,很容易接受您继承的对象的构造函数所需的任何参数,因为您不必在构造函数签名中命名这些参数,或者甚至提供你自己的默认值(让父对象的构造函数为你做这个,如上面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); }
使用模式 fruit = defaultValue(fruit,'Apple');
*PS你可以将defaultValue
函数重命名为一个简短的名称,只是不要使用default
它是javascript中的保留字.
宽松的类型检查
容易写,但是0
,''
,false
,null
和undefined
将被转换为默认值,这可能不是期望的结果.
function myFunc(requiredArg, optionalArg) { optionalArg = optionalArg || 'defaultValue'; }
严格的类型检查
更长,但涵盖了大多数情况.只有错误地指定默认值的情况才是我们undefined
作为参数传递的情况.
function myFunc(requiredArg, optionalArg) { optionalArg = typeof optionalArg !== 'undefined' ? optionalArg : 'defaultValue'; }
检查参数变量
捕获所有案例,但写起来最笨拙.
function myFunc(requiredArg, optionalArg1, optionalArg2) { optionalArg1 = arguments.length > 1 ? optionalArg1 : 'defaultValue'; optionalArg2 = arguments.length > 2 ? optionalArg2 : 'defaultValue'; }
ES6
不幸的是,目前浏览器支持很差
function myFunc(requiredArg, optionalArg = 'defaultValue') { }
使用ES2015/ES6,您可以利用Object.assign
哪些可以替代$.extend()
或_.defaults()
function myFunc(requiredArg, options = {}) { const defaults = { message: 'Hello', color: 'red', importance: 1 }; const settings = Object.assign({}, defaults, options); // do stuff }
您也可以使用这样的默认参数
function myFunc(requiredArg, { message: 'Hello', color: 'red', importance: 1 } = {}) { // do stuff }