我有一个像这样的功能(简化):
doSmthg (name, age, callback) {
callback(name, age);
}
如果没有提供年龄,我希望有一个默认值。
我知道我可以在ES6中做doSmthg(name, callback, age=42) {...}
但是我已经被告知回调应该始终是最后一个参数,因为它使对函数的调用更具可读性。
目前我找到的解决方案是执行以下操作:
doSmthg (name, age, callback) {
if (arguments.length === 2) {
age = 42;
callback = age;
}
}
但我觉得这个解决方案难以阅读。
这是一个很好的解决方案吗?还有更好的吗?
答案 0 :(得分:9)
对于这种情况,您可以使用以下内容:
function doSmthg(name, age, callback) {
if (typeof age === 'function') {
callback = age;
age = DEFAULT_VALUE;
}
//continue
}
或者您可以使用Hash of options,我认为它更好,因为根据参数的数量使代码更具可读性:
function doSmthg(options, callback) {
var name = options.name;
var age = options.age || DEFAULT_VALUE;
//continue
}
doSmthg({ name: 'batman' }, function() {});
此外,您可以使用underscore #extend
function将选项与默认值合并。
答案 1 :(得分:7)
如果您有权使用传播运营商:
function foo(...args) {
const callback = args.pop();
const [name, age = 42] = args;
// ...
}
但我认为是时候在NodeJS中使用promises了。
function foo(name, age = 42) {
return new Promise(resolve => {
setTimeout(() => resolve({name, age}), 1000);
});
}
//...
foo('Sándor').then(x => console.log(x)); // { name:"Sándor", age:42 }
使用ES6承诺,您可以摆脱所谓的“回调金字塔”,并且可以将您的功能与ES7 async-await
关键字一起使用。未来就在这里!
答案 2 :(得分:3)
function foo(args, callback){
parsed = {name:"John Doe",age:12}; //default values
for(a in args) parsed[a] = args[a];
//Arguments are accessible like parsed.name
callback(parsed);
}
function callback(args){
alert(JSON.stringify(args));
}
foo({name:"Peter",extra:2},callback);//yields {"name":"Peter","age":12,"extra":2}
foo({name:"Mark",age:92},callback); //yields {"name":"Mark","age":92}
foo({},callback); //yields {"name":"John Doe","age":12}
根据要传递的参数数量,它可能看起来过于冗长。这个概念应该是自我解释的,但是用文字表示,我们将参数分组在一个对象中,在函数内部有一个具有默认值的对象(如果需要)。然后我们用传递的默认值覆盖默认值,为我们留下一个非常清晰,干净的callback
和详细的args。
请注意,如果传递了额外的参数,那么在设置默认值的过程中不会丢失这些参数。