Establecer un valor de parámetro predeterminado para una función de JavaScript

11 minutos de lectura

Establecer un valor de parametro predeterminado para una funcion de
Tilendor

Me gustaría que una función de JavaScript tenga argumentos opcionales en los que configuro un valor predeterminado, que se usan si el valor no está definido (y se ignoran si se pasa el valor). En Ruby puedes hacerlo así:

def read_file(file, delete_after = false)
  # code
end

¿Esto funciona en JavaScript?

function read_file(file, delete_after = false) {
  // Code
}

1646960952 891 Establecer un valor de parametro predeterminado para una funcion de
tom ritter

Desde ES6/ES2015los parámetros predeterminados se encuentran en la especificación del idioma.

function read_file(file, delete_after = false) {
  // Code
}

solo funciona

Referencia: Parámetros predeterminados – MDN

Los parámetros de función predeterminados permiten que los parámetros formales se inicialicen con valores predeterminados si sin valor o indefinido esta pasado.

Tú también puedes simular predeterminado llamado parámetros a través de la desestructuración:

// the `= {}` below lets you call the function without any parameters
function myFor({ start = 5, end = 1, step = -1 } = {}) { // (A)
    // Use the variables `start`, `end` and `step` here
    ···
}

Antes de ES2015,

Hay muchas maneras, pero este es mi método preferido: te permite pasar lo que quieras, incluso falso o nulo. (typeof null == "object")

function foo(a, b) {
  a = typeof a !== 'undefined' ? a : 42;
  b = typeof b !== 'undefined' ? b : 'default_b';
  ...
}

  • También puede encapsularlo como tal: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; } y luego puedes llamarlo como a = defaultFor(a, 42);

    – Camilo Martín

    2 de septiembre de 2012 a las 5:56


  • @SiPlus y obtuviste errores de referencia adicionales de forma gratuita al intentar usar undefined objetos :p Aunque puede funcionar con algunos navegadores y puede ser más rápido, null sigue siendo un objeto y undefined es una referencia al tipo primitivo que está tratando de decir que no hay nada aquí, ni siquiera null. Vea aquí, ambos casos en pocas palabras: JavaScript/Referencia/Global_Objects/indefinido.

    – Sampo Sarrala – codidact.org

    3 de noviembre de 2012 a las 1:29


  • si comprueba la propiedad de un objeto, entonces typeof es redundante function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; } Esto no arrojará errores de referencia y es conciso.

    – Dziamid

    17 mayo 2013 a las 11:06


  • Sé que es realmente menor, pero no me gusta cómo estás asignando a = a y b = b cuando esos parámetros no están indefinidos. Además, ese operador ternario con una condición un poco complicada puede ser difícil de leer para futuros mantenedores. Preferiría la siguiente sintaxis: if (typeof a == 'undefined') a = 42 – Sin asignaciones innecesarias y un poco más fácil de leer.

    – Papá32

    9 dic 2014 a las 15:31


  • ¿Hay alguna razón para usar typeof? Parecería más sencillo simplemente hacer a === undefined. Además, de esa manera obtendrías un error de referencia si escribiste mal undefined vs ponerlo en una cadena.

    – Abe Völker

    21 mayo 2015 a las 22:04


Establecer un valor de parametro predeterminado para una funcion de
cámara rusa

function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

Esto asigna a delete_after El valor de delete_after si no es un falso valor de lo contrario asigna la cadena "my default here". Para más detalles, echa un vistazo La encuesta de Doug Crockford sobre el idioma y consulte la sección sobre Operadores.

Este enfoque no funciona si desea pasar un falso valor es decir false, null, undefined, 0 o "". Si usted requiere falso los valores que se pasarán necesitarían usar el método en la respuesta de Tom Ritter.

Cuando se trata de una cantidad de parámetros para una función, a menudo es útil permitir que el consumidor pase los argumentos de los parámetros en un objeto y luego unir estos valores con un objeto que contiene los valores predeterminados para la función

function read_file(values) {
    values = merge({ 
        delete_after : "my default here"
    }, values || {});

    // rest of code
}

// simple implementation based on $.extend() from jQuery
function merge() {
    var obj, name, copy,
        target = arguments[0] || {},
        i = 1,
        length = arguments.length;

    for (; i < length; i++) {
        if ((obj = arguments[i]) != null) {
            for (name in obj) {
                copy = obj[name];

                if (target === copy) {
                    continue;
                }
                else if (copy !== undefined) {
                    target[name] = copy;
                }
            }
        }
    }

    return target;
};

usar

// will use the default delete_after value
read_file({ file: "my file" }); 

// will override default delete_after value
read_file({ file: "my file", delete_after: "my value" }); 

  • Esto me parece insuficiente, porque puedo querer pasar en falso.

    – Tom Ritter

    21 de mayo de 2009 a las 20:11

  • Creo que es adecuado para la mayoría de las situaciones.

    – Rus Cam

    21 de mayo de 2009 a las 20:16

  • Debido a que no funciona con valores falsos, puede crear una pesadilla de mantenimiento. Un fragmento de código al que siempre se le han pasado valores verdaderos antes y de repente falla porque se pasa uno falso probablemente debería evitarse cuando se disponga de un enfoque más sólido.

    – jinglesthula

    31/10/2012 a las 20:34

  • ¿Cómo es que, en este caso, delete_after no obtiene el resultado booleano de la expresión delete_after || "my default value"?

    – xbonez

    28 de noviembre de 2012 a las 5:56


  • o bien, podría simplemente usar un valor predeterminado falso, que generalmente es un buen valor predeterminado de todos modos (por ejemplo, false para bools, cadena vacía para cadenas, 0 para números, etc.), en cuyo caso realmente no importa lo que fue aprobada en.

    – Mark Brackett

    27 de marzo de 2016 a las 1:33

Encuentro que algo simple como esto es mucho más conciso y legible personalmente.

function pick(arg, def) {
   return (typeof arg == 'undefined' ? def : arg);
}

function myFunc(x) {
  x = pick(x, 'my default');
} 

  • Actualización: si estás usando guión bajo.js ya me parece aún mejor usar _.defaults(iceCream, {flavor: "vanilla", sprinkles: "lots"});. Muchos consideran que usar el espacio de nombres global como se muestra en esta respuesta es una mala práctica. También puede considerar implementar su propia utilidad para esta tarea común (p. util.default(arg, "defaul value")) si no quiero usar guiones bajos, pero en su mayoría termino usando guiones bajos tarde o temprano de todos modos, no tiene sentido reinventar la rueda.

    – andersand

    15 de agosto de 2014 a las 20:12


  • De hecho, recomiendo este, lo uso y lo llamo “por”, que significa “parámetro o”.

    usuario2039981

    21 de abril de 2015 a las 16:59


  • No diga typeof arg == ‘indefinido’, en su lugar diga arg === indefinido

    – OsamaBinIniciar sesión

    20 oct 2015 a las 15:06

  • @OsamaBinLogin lo que dice es correcto para el JS actual: la prueba anterior persiste porque en algunos navegadores solía ser posible sobrescribir undefined con algún otro valor, haciendo que la prueba falle.

    – Alnitak

    16 de noviembre de 2015 a las 11:34

  • @Alnitak: Todavía es posible anular undefined. Por lo tanto, sigue siendo una buena idea usar typeof y 'undefined'.

    – Sr. Lance E Sloan

    14/06/2017 a las 20:27

1646960953 376 Establecer un valor de parametro predeterminado para una funcion de
Félix Kling

En ECMAScript 6, podrá escribir exactamente lo que tiene:

function read_file(file, delete_after = false) {
  // Code
}

Esto establecerá delete_after para false si no está presente o undefined. Puede usar funciones de ES6 como esta hoy con transpiladores como Babel.

Consulte el artículo de MDN para obtener más información..

Valores de parámetros predeterminados

Con ES6, puede hacer quizás uno de los modismos más comunes en JavaScript se refiere a establecer un valor predeterminado para un parámetro de función. La forma en que lo hemos hecho durante años debería parecer bastante familiar:

function foo(x,y) {
 x = x || 11;
 y = y || 31;
 console.log( x + y );
}
foo(); // 42
foo( 5, 6 ); // 11
foo( 5 ); // 36
foo( null, 6 ); // 17

Este patrón es el más usado, pero es peligroso cuando pasamos valores como

foo(0, 42)
foo( 0, 42 ); // 53 <-- Oops, not 42

¿Por qué? Porque el 0 is falsyy así el x || 11 results in 11no el directamente pasado en 0. Para solucionar este problema, algunas personas escribirán el cheque de forma más detallada de esta manera:

function foo(x,y) {
 x = (x !== undefined) ? x : 11;
 y = (y !== undefined) ? y : 31;
 console.log( x + y );
}
foo( 0, 42 ); // 42
foo( undefined, 6 ); // 17

ahora podemos examinar una buena sintaxis útil agregada a partir de ES6 para simplificar la asignación de valores predeterminados a los argumentos que faltan:

function foo(x = 11, y = 31) {
 console.log( x + y );
}

foo(); // 42
foo( 5, 6 ); // 11
foo( 0, 42 ); // 42
foo( 5 ); // 36
foo( 5, undefined ); // 36 <-- `undefined` is missing
foo( 5, null ); // 5 <-- null coerces to `0`
foo( undefined, 6 ); // 17 <-- `undefined` is missing
foo( null, 6 ); // 6 <-- null coerces to `0`

x = 11 en una declaración de función es más como x !== undefined ? x : 11 que el idioma mucho más común x || 11

Expresiones de valores predeterminados

Function los valores predeterminados pueden ser más que simples valores como 31; pueden ser cualquier expresión válida, incluso una function call:

function bar(val) {
 console.log( "bar called!" );
 return y + val;
}
function foo(x = y + 3, z = bar( x )) {
 console.log( x, z );
}
var y = 5;
foo(); // "bar called"
 // 8 13
foo( 10 ); // "bar called"
 // 10 15
y = 6;
foo( undefined, 10 ); // 9 10

Como puede ver, las expresiones de valor predeterminadas se evalúan de forma perezosa, lo que significa que solo se ejecutan si son necesarias y cuando son necesarias, es decir, cuando el argumento de un parámetro se omite o no está definido.

Una expresión de valor predeterminado puede incluso ser una llamada de expresión de función en línea, comúnmente denominada Expresión de función invocada inmediatamente. (IIFE):

function foo( x =
 (function(v){ return v + 11; })( 31 )
) {
 console.log( x );
}
foo(); // 42

1646960954 809 Establecer un valor de parametro predeterminado para una funcion de
Takács Zsolt

esa solución funciona para mí en js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}

Recomiendo encarecidamente extrema precaución al usar valores de parámetros predeterminados en javascript. A menudo crea errores cuando se usa junto con funciones de orden superior como forEach, mapy reduce. Por ejemplo, considere esta línea de código:

['1', '2', '3'].map(parseInt); // [1, NaN, NaN]

parseInt tiene un segundo parámetro opcional función parseInt(s, [radix=10]) pero el mapa llama parseInt con tres argumentos: (elemento, índicey formación).

Le sugiero que separe sus parámetros requeridos de sus argumentos valorados opcionales/predeterminados. Si su función toma 1, 2 o 3 parámetros requeridos para los cuales no tiene sentido ningún valor predeterminado, conviértalos en parámetros posicionales para la función, cualquier parámetro opcional debe seguir como atributos con nombre de un solo objeto. Si su función toma 4 o más, tal vez tenga más sentido proporcionar todos los argumentos a través de atributos de un solo parámetro de objeto.

En su caso, le sugiero que escriba su función deleteFile de esta manera: (editado por instead‘s comentarios)…

// unsafe
function read_file(fileName, deleteAfter=false) {
    if (deleteAfter) {
        console.log(`Reading and then deleting ${fileName}`);
    } else {
        console.log(`Just reading ${fileName}`);
    }
}

// better
function readFile(fileName, options) {
  const deleteAfter = !!(options && options.deleteAfter === true);
  read_file(fileName, deleteAfter);
}

console.log('unsafe...');
['log1.txt', 'log2.txt', 'log3.txt'].map(read_file);

console.log('better...');
['log1.txt', 'log2.txt', 'log3.txt'].map(readFile);

Ejecutar el fragmento anterior ilustra los peligros que acechan detrás de los valores de argumento predeterminados para parámetros no utilizados.

  • Esta “mejor solución” es bastante ilegible. Prefiero recomendar verificar el tipo de variable como typeof deleteAfter === 'bool' y lanzar Exception de lo contrario. Además, en el caso de usar métodos como map/foreach, etc., utilícelos con precaución y envuelva las funciones llamadas con una función anónima. ['1', '2', '3'].map((value) => {read_file(value);})

    – en lugar de

    26 de enero de 2019 a las 17:36


  • Ese es un buen punto. Estaba tratando de evitar el uso de bibliotecas en mi fragmento de código, pero esta expresión es bastante complicada en javascript puro. Personalmente, usaría lodash’s get método para recuperar deleteAfter. Lanzar una excepción si typeof 'deleteAfter' !== 'bool' también puede ser una buena medida prudente. No me gusta diseñar métodos que requieran que la persona que llama “tenga cuidado”. La precaución es responsabilidad de la función, no de la persona que llama. El comportamiento final debe seguir el principio de menor sorpresa.

    –Doug Coburn

    26 de enero de 2019 a las 18:18

  • Estoy de acuerdo, ese método no debe escribirse de esa manera, que llamarlo puede romper su comportamiento. Pero tenga en cuenta que la función es como el modelo y la persona que llama es como el controlador. El modelo debe encargarse del procesamiento de datos. La función (método) debe esperar que los datos se puedan pasar de manera incorrecta y manejarlos. Es por eso que verificar el tipo de parámetro más lanzar una excepción es la mejor manera. Aunque es más complejo. Pero aun así puede salvarte de rascarte la cabeza y seguir preguntando… ¡¿POR QUÉ NO FUNCIONA?! y luego… ¡¿POR QUÉ FUNCIONA?!

    – en lugar de

    26 de enero de 2019 a las 23:52

¿Ha sido útil esta solución?

Esta web utiliza cookies propias y de terceros para su correcto funcionamiento y para fines analíticos y para mostrarte publicidad relacionada con sus preferencias en base a un perfil elaborado a partir de tus hábitos de navegación. Al hacer clic en el botón Aceptar, acepta el uso de estas tecnologías y el procesamiento de tus datos para estos propósitos. Configurar y más información
Privacidad