有没有更好的方法在JavaScript中执行可选函数参数?
时间:2020-03-06 14:52:36 来源:igfitidea点击:
我一直像这样处理JavaScript中的可选参数:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || 'defaultValue';
// Do stuff
}
有更好的方法吗?
在任何情况下使用这样的||都会失败吗?
解决方案
如果传递了optionalArg,逻辑将失败,但是评估为false,请尝试使用此方法
if (typeof optionalArg === 'undefined') { optionalArg = 'default'; }
或者另一种习语:
optionalArg = (typeof optionalArg === 'undefined') ? 'default' : optionalArg;
使用任何一种最能传达我们意图的习语!
我们可以为此使用一些不同的方案。我一直在测试arguments.length:
function myFunc(requiredArg, optionalArg){
optionalArg = myFunc.arguments.length<2 ? 'defaultValue' : optionalArg;
...
-这样做可能不会失败,但是我不知道方式是否有失败的机会,只是现在我还无法想到一个实际会失败的情况...
然后,保罗提出了一个失败的方案!-)
如果我们需要插入字面量为NULL的内容,则可能会遇到一些问题。除此之外,不,我认为我们可能在正确的轨道上。
某些人选择的另一种方法是采用一个依次遍历变量列表的assoc数组。它看起来更整洁,但是我想它会稍微(非常)多地占用大量的处理/内存。
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];
// ...
}
与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)
这种方法有什么好处?
- 我们可以根据需要忽略任意多个参数-如果我们只想覆盖一个参数的值,则可以只提供该参数,而不必在有5个参数且我们只想覆盖的情况下显式传递undefined。自定义最后一个方法,就像我们需要使用其他建议的方法一样。
- 当使用从另一个对象继承的对象的构造函数时,很容易接受我们要继承的对象的构造函数所需要的任何参数,因为我们不必在构造函数签名中命名这些参数,甚至提供我们自己的默认值(让父对象的构造函数为我们完成此操作,如上
CharField调用Field的构造函数所示)。 - 继承层次结构中的子对象可以为其父构造函数自定义其自定义参数,以强制执行其自己的默认值或者确保始终使用特定值。

