我一直是这样处理 JavaScript 中的可选参数:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有没有更好的方法?
在什么情况下使用像||
这样的方式会失败?
我一直是这样处理 JavaScript 中的可选参数:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有没有更好的方法?
在什么情况下使用像||
这样的方式会失败?
如果传递了optionalArg参数但其估值为false,那么你的逻辑会失败 - 尝试使用以下替代方案
if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
或者一个替代的习语:
optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
使用最能传达你意图的习语!
我认为这是最简单、最易读的方法:
if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here
在我看来,Paul Dixon的答案不如这个易读,但这取决于个人喜好。
Insin的答案更加高级,但对于大型函数来说更有用!
编辑 11/17/2013 9:33pm:我创建了一个名为Node.js的包,使“overload”函数(方法)更容易,称为parametric。
如果你需要插入一个字面意义上的 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];
// ...
}
if (!(i in argArray))
呢?为了完整性,在这个 if
语句之前,应该检查正确的参数类型,例如 if (typeof argArray !== "object") argArray = [];
。 - Bartundefined
传递给具有默认值的参数,则通过此方式,该变量将设置为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);
}
这是其简单示例。
typeof
很快,但这并不意味着 switch
很慢——只是没有那么快而已。 - user56reinstatemonica8你可以使用一些不同的方案来实现这个。我总是通过检查 arguments.length 来测试:
function myFunc(requiredArg, optionalArg){
optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;
...
因此,它不可能失败,但我不知道你的方法是否有失败的可能性,现在我想不出任何情况会导致它失败...
然后保罗提供了一个失败的场景!-)
和Oli的回答类似,我使用一个参数对象和一个定义默认值的对象。再加上一点点语法糖...
/**
* 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
的构造函数一样)。松散类型检查
编写容易,但是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') {
}
arguments
可能会产生负面的性能影响(尽管通常并不重要)。 - T.J. Crowderfunction 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;
}
只需在全局作用域中声明此函数。
function defaultValue(variable,defaultValue){
return(typeof variable!=='undefined')?(variable):(defaultValue);
}
使用模式 fruit = defaultValue(fruit,'Apple');
*PS 你可以将defaultValue
函数重命名为一个简短的名称,但不要使用default
,它是JavaScript中的保留字。
function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }
- Camilo Martin使用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
}
/* do stuff */
}`
将来的参考链接:https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax#Browser_compatibility - jave.web
arguments
的答案。 - Justus Romijn