我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
我一直在处理JavaScript中的可选参数,如下所示:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
这样使用||会失败吗?
当前回答
这就是我的结局:
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" });
其他回答
使用ES2015/ES6,您可以利用Object.assign,它可以替换$.exd()或_.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
}
与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个参数,并且您只想自定义最后一个参数,则必须使用其他建议的方法。当为从另一个继承的对象使用构造函数Function时,很容易接受所继承对象的构造函数所需的任何参数,因为您不必在构造函数签名中命名这些参数,或者甚至提供自己的默认值(让父对象的构造函数为您实现,正如上面CharField调用Field的构造函数时所看到的那样)。继承层次结构中的子对象可以根据需要为其父构造函数自定义参数,强制使用自己的默认值或确保始终使用某个值。
我认为这是最简单、最易读的方法:
if (typeof myVariable === 'undefined') { myVariable = 'default'; }
//use myVariable here
保罗·迪克森(Paul Dixon)的回答(我个人认为)不如这一点可读,但归根结底是偏好。
impin的答案要高级得多,但对于大函数来说更有用!
2013年11月17日晚上9:33编辑:我为Node.js创建了一个包,它可以更容易地“重载”称为参数化的函数(方法)。
如果传递了optionalArg,但计算结果为false,则逻辑将失败-请尝试此选项
if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
或者另一个成语:
optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
使用哪种成语最能传达你的意图!
我不知道为什么@Paul的回复被否决,但对null的验证是一个不错的选择。也许一个更肯定的例子会更有意义:
在JavaScript中,缺少的参数就像未初始化的声明变量(仅vara1;)。相等运算符将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”稍微好一点。我不会为这一点辩护,因为这是底层API如何实现函数的问题;它不应该引起API用户的兴趣。
我还应该补充一点,这是物理上确保遗漏任何参数的唯一方法,使用in运算符,不幸的是,它无法处理参数名称,因此必须传递参数索引。
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);