有没有更好的方法在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
的构造函数所示)。 - 继承层次结构中的子对象可以为其父构造函数自定义其自定义参数,以强制执行其自己的默认值或者确保始终使用特定值。