Asignar valores por defecto a los parámetros de una función en Javascript

20 Dic 2010

A diferencia de otros lenguajes, Javascript no permite asignar directamente un valor por defecto a los parámetros de una función. Ésto resulta siempre útil cuando omitimos alguno de ellos en la llamada. Por ejemplo, en PHP tendríamos:

// Código php
function myFunction( param1, param2, param3 = 'blue' ){
 // ...
 return param1 . ' ' . param2 . ' ' . param3;
}

A la hora de llamar a esta función, podemos omitir el tercer parámetro ya que es la propia función la que se encarga de asignar un valor por defecto:

echo myFunction ( 'Hello', 'world' ); // 'hello world blue'

En JS, sin embargo, tenemos que realizar una comprobación de los parámetros ya dentro del cuerpo de la función; para ello, existen varias alternativas:

OPCIÓN BÁSICA

// Código js
function myFunction( param1, param2, param3 ){
 param3 = (param3) ? param3 : 'blue';
 // ...
 return param1 + ' ' + param2 + ' ' + param3;
}

Con el uso del operador ternario, estamos evaluando si el parámetro está definido. En caso afirmativo, le asignamos su propio valor, mientras que en caso negativo, tenemos preparado un segundo valor por defecto.

alert( myFunction( ‘Hello’, ‘world’ ) );  // Hello word blue

OPCIÓN MEJORADA:

// Código js
function myFunction( param1, param2, param3 ){
 param3 = param3 || 'blue';
 // ...
 return param1 + ' ' + param2 + ' ' + param3;
}

Con el uso del condicional implícito en JS, al invocar el valor del parámetro en la igualdad, si este no ha sido definido, se coge el alternativo.

MEJOR OPCIÓN:

// Código js
function myFunction( param1, param2, param3 ){
 param3 || ( param3 = ' blue' );
 // ...
 return param1 + ' ' + param2 + ' ' + param3;
}

Sencillo y elegante, el parámetro solo se reescribe en caso de que no haya sido definido previamente.

NOTA: Para los más puristas, hay que considerar que JSLint aún no valida las dos últimas opciones. Sin embargo, es cada vez más frecuente encontrarse estas estructuras calificadas como good patterns por los programadores más punteros.

Más:

{9} Comentarios.

  1. Martin

    Muy interesante!
    Gracias por el aporte!

  2. juan

    Me gusta mas la Opción mejorada que la Mejor opción, por ello pregunto: ¿Por que es mejor la última?
    Gracias!!!

    • Carlos Benítez

      Es una cuestión de elegancia de código:

      la Opción Mejorada, puede ser redundate ya que reasigna un término con la igualdad tanto si existe previamente como si no. Por el contrario, en la opción restante, la asignación solo se efectúa en caso de que no exista el parámetro.

      No hablaríamos exactamente de un ahorro de recursos pero si de evitar una operación que puede no ser necesaria. De ahí que la Mejor Opción sea, efectivamente, más elegante que las anteriores.

      Saludos!

  3. juan

    Cierto. Y ademas lo indicas debajo, no me había fijado.
    Gracias. Enorme blog!!

  4. Uziel

    Y que pasa con los valores falsy?. Es decir que pasa si el param3 de tu ejemplo recibiera un valor boleano. El condicional ” || ” no afectaría?? en que orden habría que ponerlo? o esto se soluciona con la opción mejorada? Porque si yo le paso un false al param3, siempre tomaría el default… que por ejemplo lo pondría a true.

    Gracias por tu respuesta… Excelente tu blog =)

  5. fcodiaz

    😮 excelete aporte.. yo siempre he utilizado la opcion basica y no se me habian ocurrido las otras dos maneras, pero de hoy en adelante implementare la “mejor opcion++”, a que me refiero con “++”?, que en efecto el comentario de Uziel tiene razon, al pasar valores 0 o false la condicion de la definicion es falsa por lo que se pasa a asignar el valor por defecto y tal vez el valor por defecto no se..mm sea -1 y yo realmente quiero que valga 0 no -1…..

    function test(p){
    p || (p=-1);
    console.log(p);
    }

    test(0); // out: -1 #fail
    test(1); // out 1 #fail
    test(false); //out -1 #fail
    test(); // out -1 #win

    lo cual es posiblemente erroneo asi que tengo algunas propuestas para solucionar esto

    “MEJOR OPCIÓN ++ ”
    function test(p){
    p!==undefined || (p=-1)
    console.log(p);
    }

    test(0); //out: 0 #win
    test(1); // out: 1 #win
    test(false); //out: false #win
    test(); //out:: -1 #win

    pero simpre hacer p!==undefined.. amm vamos a ponerle un poco de estilo

    “MEJOR OPCIÓN ++ con STYLE”

    function test(p){
    var d;
    p !== d || ( p=-1 )
    console.log(p);
    }

    test(0); //out: 0 #win
    test(1); // out: 1 #win
    test(false); //out: false #win
    test(); //out:: -1 #win

    creo que esta es la que usaré de hoy en adelante esta seria la version “++”.. pero tambien tengo una version “#”

    “MEJOR OPCIÓN#”
    function ud(p){
    var b;
    return p !== b;
    }

    function test(p){
    var d;
    ud(p) || (p=-1)
    console.log(p);
    }

    test(0); //out: 0 #win
    test(1); // out: 1 #win
    test(false); //out: false #win
    test(); //out:: -1 #win

    con esta ultima nos ahoramos unos caracteres pero tenemos que definir una funcion para hacer la comparacion con undefined, el unico problema que lo veo es que nunca podre pasar undefined a los parametros y estos tubiera un valor por defecto y yo quisiera que REALMENTE valieran undefined XÐ (¿aunque para que quedria hacer eso :S?)

  6. Sahib

    Esto no funciona correctamente si se utilizan valores “falsos” como null, 0 (cero), false en si cualquier valor falso en JavaScript, en ese caso se cumpliría la condición y se asignaria el valor por default al parametro.

    Para evitar esto no hay otra manera más fiable que comprar directamente el parametro con undefined:

    param3 = (param3 === undefined) ? 'valor_por_default' : param3;
    

    Opino que esa es la manera más segura.

  7. Alejandro

    Buenísimo el aporte, funciona de mil maravillas.

  8. David

    Gracias ! , excelente

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *