我一直在处理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
}
其他回答
function Default(variable, new_value)
{
if(new_value === undefined) { return (variable === undefined) ? null : variable; }
return (variable === undefined) ? new_value : variable;
}
var a = 2, b = "hello", c = true, d;
var test = Default(a, 0),
test2 = Default(b, "Hi"),
test3 = Default(c, false),
test4 = Default(d, "Hello world");
window.alert(test + "\n" + test2 + "\n" + test3 + "\n" + test4);
http://jsfiddle.net/mq60hqrf/
我尝试了这里提到的一些选项,并对它们进行了性能测试。此时此刻,逻辑学家似乎是最快的。尽管这会随着时间的推移而改变(不同的JavaScript引擎版本)。
以下是我的结果(Microsoft Edge 20.10240.16384.0):
Function executed Operations/sec Statistics
TypeofFunction('test'); 92,169,505 ±1.55% 9% slower
SwitchFuntion('test'); 2,904,685 ±2.91% 97% slower
ObjectFunction({param1: 'test'}); 924,753 ±1.71% 99% slower
LogicalOrFunction('test'); 101,205,173 ±0.92% fastest
TypeofFunction2('test'); 35,636,836 ±0.59% 65% slower
此性能测试可在以下位置轻松复制:http://jsperf.com/optional-parameters-typeof-vs-switch/2
这是测试代码:
<script src="https://ajax.googleapis.com/ajax/libs/jquery/1/jquery.min.js"></script>
<script>
Benchmark.prototype.setup = function() {
function TypeofFunction(param1, optParam1, optParam2, optParam3) {
optParam1 = (typeof optParam1 === "undefined") ? "Some default" : optParam1;
optParam2 = (typeof optParam2 === "undefined") ? "Another default" : optParam2;
optParam3 = (typeof optParam3 === "undefined") ? "Some other default" : optParam3;
}
function TypeofFunction2(param1, optParam1, optParam2, optParam3) {
optParam1 = defaultValue(optParam1, "Some default");
optParam2 = defaultValue(optParam2, "Another default");
optParam3 = defaultValue(optParam3, "Some other default");
}
function defaultValue(variable, defaultValue) {
return (typeof variable !== 'undefined') ? (variable) : (defaultValue);
}
function SwitchFuntion(param1, optParam1, optParam2, optParam3) {
switch (arguments.length - 1) { // <-- 1 is number of required arguments
case 0:
optParam1 = 'Some default';
case 1:
optParam2 = 'Another default';
case 2:
optParam3 = 'Some other default';
}
}
function ObjectFunction(args) {
var defaults = {
optParam1: 'Some default',
optParam2: 'Another default',
optParam3: 'Some other default'
}
args = $.extend({}, defaults, args);
}
function LogicalOrFunction(param1, optParam1, optParam2, optParam3) {
optParam1 || (optParam1 = 'Some default');
optParam2 || (optParam1 = 'Another default');
optParam3 || (optParam1 = 'Some other default');
}
};
</script>
与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的构造函数时所看到的那样)。继承层次结构中的子对象可以根据需要为其父构造函数自定义参数,强制使用自己的默认值或确保始终使用某个值。
这些版本比操作员版本的类型短。
function foo(a, b) {
a !== undefined || (a = 'defaultA');
if(b === undefined) b = 'defaultB';
...
}
如果我错了,请纠正我,但这似乎是最简单的方法(无论如何,对于一个论点):
function myFunction(Required,Optional)
{
if (arguments.length<2) Optional = "Default";
//Your code
}