我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
当前回答
如果我错了,请纠正我,但这似乎是最简单的方法(无论如何,对于一个论点):
function myFunction(Required,Optional)
{
if (arguments.length<2) Optional = "Default";
//Your code
}
其他回答
在一个项目中,我注意到我对可选参数和设置重复了太多,所以我创建了一个类来处理类型检查并分配一个默认值,从而生成整洁可读的代码。看看示例,让我知道这是否适用于您。
var myCar = new Car('VW', {gearbox:'automatic', options:['radio', 'airbags 2x']});
var myOtherCar = new Car('Toyota');
function Car(brand, settings) {
this.brand = brand;
// readable and adjustable code
settings = DefaultValue.object(settings, {});
this.wheels = DefaultValue.number(settings.wheels, 4);
this.hasBreaks = DefaultValue.bool(settings.hasBreaks, true);
this.gearbox = DefaultValue.string(settings.gearbox, 'manual');
this.options = DefaultValue.array(settings.options, []);
// instead of doing this the hard way
settings = settings || {};
this.wheels = (!isNaN(settings.wheels)) ? settings.wheels : 4;
this.hasBreaks = (typeof settings.hasBreaks !== 'undefined') ? (settings.hasBreaks === true) : true;
this.gearbox = (typeof settings.gearbox === 'string') ? settings.gearbox : 'manual';
this.options = (typeof settings.options !== 'undefined' && Array.isArray(settings.options)) ? settings.options : [];
}
使用此类:
(function(ns) {
var DefaultValue = {
object: function(input, defaultValue) {
if (typeof defaultValue !== 'object') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? input : defaultValue;
},
bool: function(input, defaultValue) {
if (typeof defaultValue !== 'boolean') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? (input === true) : defaultValue;
},
number: function(input, defaultValue) {
if (isNaN(defaultValue)) throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined' && !isNaN(input)) ? parseFloat(input) : defaultValue;
},
// wrap the input in an array if it is not undefined and not an array, for your convenience
array: function(input, defaultValue) {
if (typeof defaultValue === 'undefined') throw new Error('invalid defaultValue type');
return (typeof input !== 'undefined') ? (Array.isArray(input) ? input : [input]) : defaultValue;
},
string: function(input, defaultValue) {
if (typeof defaultValue !== 'string') throw new Error('invalid defaultValue type');
return (typeof input === 'string') ? input : defaultValue;
},
};
ns.DefaultValue = DefaultValue;
}(this));
如果您广泛使用默认值,这看起来更容易理解:
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函数重命名为短名称,只是不要使用默认值,这是javascript中的保留字。
这就是我的结局:
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 ...
}
这样调用:
WhoLikesCake({ b : "I do" });
理想情况下,您可以进行重构以传递一个对象并将其与默认对象合并,因此传递参数的顺序无关紧要(请参阅下面的答案第二部分)。
然而,如果你只是想要一些快速、可靠、易于使用且体积不大的东西,请尝试一下:
对任意数量的默认参数的快速修复
它的伸缩性很好:每个新默认值的额外代码最少您可以将其粘贴到任何位置:只需更改所需参数和变量的数量如果您想将undefined传递给具有默认值的参数,那么这种方式会将变量设置为undefineed。此页面上的大多数其他选项将用默认值替换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的答案类似,但很容易扩展到任意数量的默认参数,更容易更新,并且使用的参数不是Function.arguments。
传递和合并对象以提高灵活性
上面的代码和许多默认参数的方法一样,不能按顺序传递参数,例如,传递optionalC,但让optionalB返回默认值。
一个很好的选择是传递对象并与默认对象合并。这也有利于可维护性(只需注意保持代码可读,这样未来的合作者就不会对您传递的对象的可能内容进行猜测)。
使用jQuery的示例。如果不使用jQuery,可以改用Undercore的_.defaults(对象,默认值)或浏览以下选项:
function myFunc( args ) {
var defaults = {
optionalA: 'Some default',
optionalB: 'Another default',
optionalC: 'Some other default'
};
args = $.extend({}, defaults, args);
}
这是一个简单的例子。
对undefined的测试是不必要的,也不像可能的那样健壮,因为正如user568458所指出的,如果通过null或false,则提供的解决方案将失败。API的用户可能认为false或null将强制方法避免该参数。
function PaulDixonSolution(required, optionalArg){
optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
console.log(optionalArg);
};
PaulDixonSolution("required");
PaulDixonSolution("required", "provided");
PaulDixonSolution("required", null);
PaulDixonSolution("required", false);
结果是:
defaultValue
provided
null
false
最后两个可能很糟糕。相反,请尝试:
function bulletproof(required, optionalArg){
optionalArg = optionalArg ? optionalArg : "defaultValue";;
console.log(optionalArg);
};
bulletproof("required");
bulletproof("required", "provided");
bulletproof("required", null);
bulletproof("required", false);
结果是:
defaultValue
provided
defaultValue
defaultValue
唯一一个不理想的情况是,当您实际拥有布尔值或故意为空的可选参数时。