retornar - ¿Hay una mejor manera de hacer parámetros de función opcionales en JavaScript?
pasar variables entre funciones javascript (28)
arg || ''default''
arg || ''default''
es una excelente manera y funciona para el 90% de los casosFalla cuando necesitas pasar valores que podrían ser ''falsos''
-
false
-
0
-
NaN
-
""
Para estos casos, deberá ser un poco más detallado y verificar si
undefined
-
También tenga cuidado cuando tenga argumentos opcionales primero, debe conocer los tipos de todos sus argumentos
Esta pregunta ya tiene una respuesta aquí:
Siempre he manejado parámetros opcionales en JavaScript como este:
function myFunc(requiredArg, optionalArg){
optionalArg = optionalArg || ''defaultValue'';
// Do stuff
}
Hay una mejor manera de hacerlo?
¿Hay algún caso en el que utilizando ||
así va a fallar?
Aquí está mi solución. Con esto puedes dejar cualquier parámetro que quieras. El orden de los parámetros opcionales no es importante y puede agregar validación personalizada.
function YourFunction(optionalArguments) {
//var scope = this;
//set the defaults
var _value1 = ''defaultValue1'';
var _value2 = ''defaultValue2'';
var _value3 = null;
var _value4 = false;
//check the optional arguments if they are set to override defaults...
if (typeof optionalArguments !== ''undefined'') {
if (typeof optionalArguments.param1 !== ''undefined'')
_value1 = optionalArguments.param1;
if (typeof optionalArguments.param2 !== ''undefined'')
_value2 = optionalArguments.param2;
if (typeof optionalArguments.param3 !== ''undefined'')
_value3 = optionalArguments.param3;
if (typeof optionalArguments.param4 !== ''undefined'')
//use custom parameter validation if needed, in this case for javascript boolean
_value4 = (optionalArguments.param4 === true || optionalArguments.param4 === ''true'');
}
console.log(''value summary of function call:'');
console.log(''value1: '' + _value1);
console.log(''value2: '' + _value2);
console.log(''value3: '' + _value3);
console.log(''value4: '' + _value4);
console.log('''');
}
//call your function in any way you want. You can leave parameters. Order is not important. Here some examples:
YourFunction({
param1: ''yourGivenValue1'',
param2: ''yourGivenValue2'',
param3: ''yourGivenValue3'',
param4: true,
});
//order is not important
YourFunction({
param4: false,
param1: ''yourGivenValue1'',
param2: ''yourGivenValue2'',
});
//uses all default values
YourFunction();
//keeps value4 false, because not a valid value is given
YourFunction({
param4: ''not a valid bool''
});
Con ES2015 / ES6 puede aprovechar Object.assign
que puede reemplazar $.extend()
o _.defaults()
function myFunc(requiredArg, options = {}) {
const defaults = {
message: ''Hello'',
color: ''red'',
importance: 1
};
const settings = Object.assign({}, defaults, options);
// do stuff
}
También puedes usar argumentos predeterminados como este
function myFunc(requiredArg, { message: ''Hello'', color: ''red'', importance: 1 } = {}) {
// do stuff
}
Corríjame si me equivoco, pero esta parece la forma más simple (para un argumento, de todos modos):
function myFunction(Required,Optional)
{
if (arguments.length<2) Optional = "Default";
//Your code
}
Durante un proyecto noté que me estaba repitiendo demasiado con los parámetros y configuraciones opcionales, así que hice una clase que controla la comprobación de tipo y asigna un valor predeterminado que da como resultado un código limpio y legible. Mira el ejemplo y hazme saber si esto funciona para ti.
var myCar = new Car(''VW'', {gearbox:''automatic'', options:[''radio'', ''airbags 2x'']});
var myOtherCar = new Car(''Toyota'');
function Car(brand, settings) {
this.brand = brand;
// readable and adjustable code
settings = DefaultValue.object(settings, {});
this.wheels = DefaultValue.number(settings.wheels, 4);
this.hasBreaks = DefaultValue.bool(settings.hasBreaks, true);
this.gearbox = DefaultValue.string(settings.gearbox, ''manual'');
this.options = DefaultValue.array(settings.options, []);
// instead of doing this the hard way
settings = settings || {};
this.wheels = (!isNaN(settings.wheels)) ? settings.wheels : 4;
this.hasBreaks = (typeof settings.hasBreaks !== ''undefined'') ? (settings.hasBreaks === true) : true;
this.gearbox = (typeof settings.gearbox === ''string'') ? settings.gearbox : ''manual'';
this.options = (typeof settings.options !== ''undefined'' && Array.isArray(settings.options)) ? settings.options : [];
}
Utilizando esta clase:
(function(ns) {
var DefaultValue = {
object: function(input, defaultValue) {
if (typeof defaultValue !== ''object'') throw new Error(''invalid defaultValue type'');
return (typeof input !== ''undefined'') ? input : defaultValue;
},
bool: function(input, defaultValue) {
if (typeof defaultValue !== ''boolean'') throw new Error(''invalid defaultValue type'');
return (typeof input !== ''undefined'') ? (input === true) : defaultValue;
},
number: function(input, defaultValue) {
if (isNaN(defaultValue)) throw new Error(''invalid defaultValue type'');
return (typeof input !== ''undefined'' && !isNaN(input)) ? parseFloat(input) : defaultValue;
},
// wrap the input in an array if it is not undefined and not an array, for your convenience
array: function(input, defaultValue) {
if (typeof defaultValue === ''undefined'') throw new Error(''invalid defaultValue type'');
return (typeof input !== ''undefined'') ? (Array.isArray(input) ? input : [input]) : defaultValue;
},
string: function(input, defaultValue) {
if (typeof defaultValue !== ''string'') throw new Error(''invalid defaultValue type'');
return (typeof input === ''string'') ? input : defaultValue;
},
};
ns.DefaultValue = DefaultValue;
}(this));
En ECMAScript 2015 (también conocido como "ES6") puede declarar valores de argumento predeterminados en la declaración de función:
function myFunc(requiredArg, optionalArg = ''defaultValue'') {
// do stuff
}
Más sobre ellos en este artículo sobre MDN (a pesar del título del artículo, se les llama "argumentos", no "parámetros", en JavaScript).
Actualmente, esto solo es compatible con Firefox , pero como el estándar se ha completado, espere que el soporte mejore rápidamente.
Encuentro que esta es la forma más simple y legible:
if (typeof myVariable === ''undefined'') { myVariable = ''default''; }
//use myVariable here
La respuesta de Paul Dixon (en mi humilde opinión) es menos legible que esto, pero se trata de preferencias.
¡La respuesta de Insin es mucho más avanzada, pero mucho más útil para grandes funciones!
EDITAR 11/17/2013 9:33 pm: He creado un paquete para Node.js que hace que sea más fácil "sobrecargar" funciones (métodos) llamadas parametric .
Esos son más cortos que la versión del operador typeof.
function foo(a, b) {
a !== undefined || (a = ''defaultA'');
if(b === undefined) b = ''defaultB'';
...
}
Esto es lo que terminé con:
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 ...
}
Llamado así:
WhoLikesCake({ b : "I do" });
Estoy acostumbrado a ver algunas variaciones básicas en el manejo de variables opcionales. A veces, las versiones relajadas son útiles.
function foo(a, b, c) {
a = a || "default"; // Matches 0, "", null, undefined, NaN, false.
a || (a = "default"); // Matches 0, "", null, undefined, NaN, false.
if (b == null) { b = "default"; } // Matches null, undefined.
if (typeof c === "undefined") { c = "default"; } // Matches undefined.
}
El valor predeterminado falso utilizado con la variable a
se usa, por ejemplo, ampliamente en Backbone.js .
Gente -
Después de ver estas y otras soluciones, probé varias utilizando un fragmento de código originalmente de W3Schools como base. Puedes encontrar lo que funciona en lo siguiente. Cada uno de los elementos comentados también funciona y es de esa manera para permitirle experimentar simplemente eliminando comentarios individuales. Para ser claros, es el parámetro "eyecolor" que no se está definiendo.
function person(firstname, lastname, age, eyecolor)
{
this.firstname = firstname;
this.lastname = lastname;
this.age = age;
this.eyecolor = eyecolor;
// if(null==eyecolor)
// this.eyecolor = "unknown1";
//if(typeof(eyecolor)===''undefined'')
// this.eyecolor = "unknown2";
// if(!eyecolor)
// this.eyecolor = "unknown3";
this.eyecolor = this.eyecolor || "unknown4";
}
var myFather = new person("John", "Doe", 60);
var myMother = new person("Sally", "Rally", 48, "green");
var elem = document.getElementById("demo");
elem.innerHTML = "My father " +
myFather.firstname + " " +
myFather.lastname + " is " +
myFather.age + " with " +
myFather.eyecolor + " eyes.<br/>" +
"My mother " +
myMother.firstname + " " +
myMother.lastname + " is " +
myMother.age + " with " +
myMother.eyecolor + " eyes.";
La prueba para undefined es innecesaria y no es tan robusta como podría ser porque, como señaló el usuario 568458, la solución provista falla si se pasa nulo o falso. Los usuarios de su API pueden pensar que falso o nulo forzarían el método para evitar ese parámetro.
function PaulDixonSolution(required, optionalArg){
optionalArg = (typeof optionalArg === "undefined") ? "defaultValue" : optionalArg;
console.log(optionalArg);
};
PaulDixonSolution("required");
PaulDixonSolution("required", "provided");
PaulDixonSolution("required", null);
PaulDixonSolution("required", false);
El resultado es:
defaultValue
provided
null
false
Esos dos últimos son potencialmente malos. En su lugar, intente:
function bulletproof(required, optionalArg){
optionalArg = optionalArg ? optionalArg : "defaultValue";;
console.log(optionalArg);
};
bulletproof("required");
bulletproof("required", "provided");
bulletproof("required", null);
bulletproof("required", false);
Lo que resulta en:
defaultValue
provided
defaultValue
defaultValue
El único escenario en el que esto no es óptimo es cuando realmente tiene parámetros opcionales que están destinados a ser booleanos o nulos intencionales.
Llegó a esta pregunta, buscando parámetros predeterminados en EcmaScript 2015 , por lo que solo menciono ...
Con ES6 podemos hacer parámetros por defecto :
function doSomething(optionalParam = "defaultValue"){
console.log(optionalParam);//not required to check for falsy values
}
doSomething(); //"defaultValue"
doSomething("myvalue"); //"myvalue"
Lo ideal sería refactorizar para pasar un objeto y merge con un objeto predeterminado, por lo que no importa el orden en que se pasen los argumentos (consulte la segunda sección de esta respuesta, a continuación).
Sin embargo, si solo desea algo rápido, confiable, fácil de usar y no voluminoso, intente esto:
Una solución rápida y limpia para cualquier número de argumentos predeterminados
- Escala con elegancia: código extra mínimo para cada nuevo valor predeterminado
- Puede pegarlo en cualquier lugar: simplemente cambie el número de argumentos y variables requeridos
- Si desea pasar
undefined
a un argumento con un valor predeterminado, de esta manera, la variable se establece comoundefined
. La mayoría de las otras opciones en esta página reemplazaríanundefined
con el valor predeterminado.
Aquí hay un ejemplo para proporcionar valores predeterminados para tres argumentos opcionales (con dos argumentos requeridos)
function myFunc( requiredA, requiredB, optionalA, optionalB, optionalC ) {
switch (arguments.length - 2) { // 2 is the number of required arguments
case 0: optionalA = ''Some default'';
case 1: optionalB = ''Another default'';
case 2: optionalC = ''Some other default'';
// no breaks between cases: each case implies the next cases are also needed
}
}
Demo simple . Esto es similar a la respuesta de Roenving , pero se puede extender fácilmente a cualquier número de argumentos predeterminados, es más fácil de actualizar y utiliza arguments
no son Function.arguments
.
Pasar y fusionar objetos para una mayor flexibilidad.
El código anterior, al igual que muchas formas de hacer argumentos predeterminados, no puede pasar los argumentos fuera de secuencia, por ejemplo, pasar la optionalC
pero dejando que la optionalB
B vuelva a su valor predeterminado.
Una buena opción para eso es pasar objetos y fusionarlos con un objeto predeterminado. Esto también es bueno para la capacidad de mantenimiento (solo tenga cuidado de mantener su código legible, para que los futuros colaboradores no se queden adivinando sobre los posibles contenidos de los objetos que pasa).
Ejemplo usando jQuery. Si no usa jQuery, en su lugar podría usar los _.defaults(object, defaults)
los _.defaults(object, defaults)
o merge :
function myFunc( args ) {
var defaults = {
optionalA: ''Some default'',
optionalB: ''Another default'',
optionalC: ''Some other default''
};
args = $.extend({}, defaults, args);
}
Aquí hay un ejemplo simple de ello en acción .
No sé por qué la respuesta de @ Paul ha sido rechazada, pero la validación contra null
es una buena opción. Tal vez un ejemplo más afirmativo tenga mejor sentido:
En JavaScript, un parámetro perdido es como una variable declarada que no está inicializada (solo var a1;
). Y el operador de igualdad convierte lo no definido en nulo, por lo que esto funciona muy bien con los tipos de valor y los objetos, y así es como CoffeeScript maneja los parámetros opcionales.
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...'';
//...
}
Sin embargo, existe la preocupación de que para la mejor semántica es typeof variable === ''undefined''
es ligeramente mejor. No estoy dispuesto a defender esto, ya que es la cuestión de la API subyacente cómo se implementa una función; no debe interesar al usuario de la API.
También debo agregar que aquí está la única manera de asegurarse físicamente de que no se haya perdido ningún argumento, utilizando el operador in
que, lamentablemente, no funciona con los nombres de los parámetros, por lo que debe pasar un índice de los arguments
.
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);
Parece que la forma más segura, para lidiar con todos los / cualquier tipo de argumentos falsos suministrados antes de decidir usar el valor predeterminado , es verificar la existencia / presencia del argumento opcional en la función invocada.
Confiando en los argumentos creación de miembro de objeto que ni siquiera se crea si falta el argumento, independientemente del hecho de que podría ser declarado, podemos escribir su función de esta manera:
function myFunc(requiredArg, optionalArg){
optionalArg = 1 in arguments ? optionalArg : ''defaultValue'';
//do stuff
}
Utilizando este comportamiento: Podemos verificar de forma segura y arbitraria y explícita cualquier valor faltante en la lista de argumentos cuando sea necesario para asegurarnos de que la función obtenga un cierto valor requerido en su procedimiento.
En el siguiente código de demostración, pondremos deliberadamente un valor indefinido y sin tipo de escritura como un valor predeterminado para poder determinar si puede fallar en valores de argumento falsos, como 0 falso, etc., o si se comporta como se espera.
function argCheck( arg1, arg2, arg3 ){
arg1 = 0 in arguments || undefined;
arg2 = 1 in arguments || false;
arg3 = 2 in arguments || 0;
var arg4 = 3 in arguments || null;
console.log( arg1, arg2, arg3, arg4 )
}
Ahora, verifique algunos valores-argumento falsos para ver si su presencia se detecta correctamente y por lo tanto se evalúa como verdadera :
argCheck( "", 0, false, null );
>> true true true true
Lo que significa que no fallaron el reconocimiento de / como valores de argumento esperados. Aquí tenemos una verificación con todos los argumentos que faltan, que según nuestros algoritmos deberían adquirir sus valores predeterminados incluso si son falsos .
argCheck( );
>> undefined false 0 null
Como podemos ver, los argumentos arg1, arg2, arg3 y el arg4 no declarado están devolviendo sus valores predeterminados exactos, según lo ordenado. Debido a que ahora nos hemos asegurado de que funcione, podemos reescribir la función que realmente podrá usarlas como en el primer ejemplo usando: ya sea o una condición ternaria .
En las funciones que tienen más de un argumento opcional, un bucle, podría habernos ahorrado algunos bits. Pero como los nombres de los argumentos no se inicializan si no se suministran sus valores, ya no podemos acceder a ellos por nombres, incluso si hemos escrito un valor predeterminado mediante programación, solo podemos acceder a ellos por los argumentos [índice], lo que hace inútil la legibilidad del código.
Pero aparte de este inconveniente, que en ciertas situaciones de codificación puede ser totalmente aceptable, hay otro problema no contabilizado para los valores predeterminados de argumentos múltiples y arbitrarios. Que puede y debe considerarse un error, ya que ya no podemos omitir argumentos, como podríamos haberlo sido, sin dar un valor, en una sintaxis como:
argCheck("a",,22,{});
Porque va a tirar! Lo que nos hace imposible sustituir nuestro argumento con un tipo falso específico de nuestro valor predeterminado deseado. Lo cual es estúpido, ya que el objeto de argumentos es un objeto similar a una matriz y se espera que admita esta sintaxis y convención tal como están, de forma nativa o por defecto.
Debido a esta decisión miope, ya no podemos esperar escribir una función como esta:
function argCheck( ) {
var _default = [undefined, 0, false, null ],
_arg = arguments;
for( var x in _default ) {
x in _arg ? 1 : _arg[x] = _default[x];
}
console.log( _arg[0],_arg[1],_arg[2],_arg[3] );
}
en cuyo caso, podríamos escribir cada valor predeterminado de un tipo deseado en la fila de argumentos y poder acceder al menos a ellos mediante args.index.
Por ejemplo, esta llamada de función produciría:
argCheck();
>>undefined 0 false null
como se define en nuestra matriz predeterminada de valores de argumentos. Sin embargo, lo siguiente es todavía posible:
argCheck({})
>>Object { } 0 false null
argCheck({}, [])
>>Object { } Array [ ] false null
Pero lamentablemente no:
argCheck("a",,,22);
>>SyntaxError: expected expression, got '',''
Lo que de otra manera se estaría registrando:
>>a 0 false 22
¡Pero eso está en un mundo mejor! Sin embargo, para la pregunta original, la función superior funcionará bien. p.ej:
function argCheck( arg, opt ) {
1 in arguments ? 1 : opt = "default";
console.log( arg, opt );
}
ps: perdón por no conservar los tipos de valores predeterminados elegidos en las entradas de mis argumentos al escribirlos.
Probé algunas de las opciones mencionadas aquí y el rendimiento las probé. En este momento el lógico parece ser el más rápido. Aunque esto está sujeto a cambios en el tiempo (diferentes versiones del motor de JavaScript).
Estos son mis resultados (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
Esta prueba de rendimiento se puede replicar fácilmente en: http://jsperf.com/optional-parameters-typeof-vs-switch/2
Este es el código de la prueba:
<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>
Puedes usar algunos esquemas diferentes para eso. Siempre he probado para argumentos.
function myFunc(requiredArg, optionalArg){
optionalArg = myFunc.arguments.length<2 ? ''defaultValue'' : optionalArg;
...
- al hacerlo, es posible que no pueda fallar, pero no sé si tu manera tiene posibilidades de fallar, ahora mismo no puedo pensar en un escenario, donde realmente podría fallar ...
Y luego Pablo proporcionó un escenario fallido!
Si está utilizando los valores predeterminados ampliamente, esto parece mucho más legible:
function usageExemple(a,b,c,d){
//defaults
a=defaultValue(a,1);
b=defaultValue(b,2);
c=defaultValue(c,4);
d=defaultValue(d,8);
var x = a+b+c+d;
return x;
}
Solo declara esta función en el ámbito global.
function defaultValue(variable,defaultValue){
return(typeof variable!==''undefined'')?(variable):(defaultValue);
}
Patrón de uso fruit = defaultValue(fruit,''Apple'');
* PS: puede cambiar el nombre de la función defaultValue
a un nombre corto, simplemente no use el default
, es una palabra reservada en javascript.
Si estás usando la biblioteca de Underscore (deberías, es una biblioteca impresionante):
_.defaults(optionalArg, ''defaultValue'');
Si necesita lanzar un NULL
literal, entonces podría tener algunos problemas. Aparte de eso, no, creo que probablemente estés en el camino correcto.
El otro método que algunas personas eligen es tomar una gran variedad de variables iterando a través de la lista de argumentos. Se ve un poco más ordenado, pero me imagino que requiere un poco más de proceso y memoria.
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];
// ...
}
Similar a la respuesta de Oli, uso un argumento Objeto y un Objeto que define los valores predeterminados. Con un poco de azúcar ...
/**
* 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
}
... Esto se puede hacer un poco mejor.
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)
¿Qué tiene de bueno este método?
- Puede omitir tantos argumentos como desee: si solo desea anular el valor de un argumento, solo puede proporcionar ese argumento, en lugar de tener que pasar explícitamente
undefined
cuando, digamos que hay 5 argumentos y que solo desea personalizar el la última, como tendría que ver con algunos de los otros métodos sugeridos. - Cuando trabaje con una función constructora para un objeto que hereda de otro, es fácil aceptar cualquier argumento que sea requerido por el constructor del Objeto del que está heredando, ya que no tiene que nombrar esos argumentos en su firma de constructor. o incluso proporcione sus propios valores predeterminados (deje que el constructor del Objeto primario haga eso por usted, como se vio anteriormente cuando
CharField
llamaField
constructor deField
). - Los objetos secundarios en las jerarquías de herencia pueden personalizar los argumentos para su constructor principal según lo consideren adecuado, imponiendo sus propios valores predeterminados o asegurándose de que siempre se utilizará un determinado valor.
Su lógica falla si se pasa opcionalArg, pero se evalúa como falsa: intente esto como una alternativa
if (typeof optionalArg === ''undefined'') { optionalArg = ''default''; }
O un idioma alternativo:
optionalArg = (typeof optionalArg === ''undefined'') ? ''default'' : optionalArg;
¡Usa el lenguaje que mejor te comunique la intención!
Comprobación de tipo suelto
Fácil de escribir, pero 0
, ''''
, false
, null
e undefined
se convertirán al valor predeterminado, lo que podría no ser el resultado esperado.
function myFunc(requiredArg, optionalArg) {
optionalArg = optionalArg || ''defaultValue'';
}
Verificación estricta
Más largo, pero cubre la mayoría de los casos. El único caso donde asigna incorrectamente un valor predeterminado es cuando pasamos undefined
como parámetro.
function myFunc(requiredArg, optionalArg) {
optionalArg = typeof optionalArg !== ''undefined'' ? optionalArg : ''defaultValue'';
}
Comprobando variables de argumentos
Captura todos los casos pero es el más torpe de escribir.
function myFunc(requiredArg, optionalArg1, optionalArg2) {
optionalArg1 = arguments.length > 1 ? optionalArg1 : ''defaultValue'';
optionalArg2 = arguments.length > 2 ? optionalArg2 : ''defaultValue'';
}
ES6
Desafortunadamente esto tiene un soporte de navegador muy pobre en este momento
function myFunc(requiredArg, optionalArg = ''defaultValue'') {
}
En todos los casos en los que optionalArg sea falsy, terminará con defaultValue.
function myFunc(requiredArg, optionalArg) {
optionalArg = optionalArg || ''defaultValue'';
console.log(optionalArg);
// Do stuff
}
myFunc(requiredArg);
myFunc(requiredArg, null);
myFunc(requiredArg, undefined);
myFunc(requiredArg, "");
myFunc(requiredArg, 0);
myFunc(requiredArg, false);
Todos los valores predeterminados del valor de registro anterior, porque todos los 6 son falsos. En el caso 4, 5, 6 puede que no esté interesado en establecer opcionalArg como valor predeterminado, pero se establece porque son falsos
Te sugiero que uses ArgueJS esta manera:
function myFunc(){
arguments = __({requiredArg: undefined, optionalArg: [undefined: ''defaultValue''})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
También puede reemplazarlo undefined
por el tipo de argumento que espera recibir, como este:
function myFunc(){
arguments = __({requiredArg: Number, optionalArg: [String: ''defaultValue''})
//do stuff, using arguments.requiredArg and arguments.optionalArg
// to access your arguments
}
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);
function foo(requiredArg){
if(arguments.length>1) var optionalArg = arguments[1];
}