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


Me gustaría que una función de JavaScript tenga argumentos opcionales en los que establezco un valor predeterminado, que se usa si el valor no está definido. En Ruby puedes hacerlo así:

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

Funciona esto en JavaScript?

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

Answers



Desde ES6 / ES2015, los parámetros predeterminados están 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 inicializar parámetros formales con valores predeterminados si no se pasa ningún valor o indefinido .

También puede simular los parámetros nombrados por defecto 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
    ···
}

Pre ES2015 ,

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

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



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 valor de falsey , de lo contrario asigna la cadena "my default here" . Para obtener más detalles, consulte la encuesta de Doug Crockford sobre el idioma y consulte la sección sobre Operadores .

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

Al tratar con una serie 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 fusionar estos valores con un objeto que contenga 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" }); 



Encuentro que algo tan simple como este 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');
} 



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

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

Esto establecerá delete_after en false si no está presente o undefined . Puede utilizar funciones de ES6 como esta hoy con transpilers como Babel .

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




Valores de parámetros predeterminados

Con ES6, puede hacer quizás una de las expresiones idiomáticas más comunes en JavaScript relacionada con la configuración de un valor predeterminado para un parámetro de función. La forma en que hemos hecho esto durante años debería ser 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 utilizado, pero es peligroso cuando pasamos valores como

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

¿Por qué? Porque el 0 is falsy , y entonces el x || 11 results in 11 x || 11 results in 11 , no el aprobado directamente en 0. Para solucionar este problema, algunas personas escribirán el cheque más detalladamente de la siguiente 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 faltantes:

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 parecido a x !== undefined ? x : 11 x !== undefined ? x : 11 que el idioma mucho más común x || 11 x || 11

Expresiones de valor predeterminado

Function valores predeterminados de Function 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 diferida, lo que significa que solo se ejecutan si se necesitan, es decir, cuando el argumento de un parámetro se omite o no se define.

Una expresión de valor por defecto puede incluso ser una llamada de expresión de función en línea, comúnmente conocida como Expresión de Función Invocada Inmediatamente (IIFE) :

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



esa solución es trabajo para mí en js:

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



Solo use una comparación explícita con undefined.

function read_file(file, delete_after)
{
    if(delete_after === undefined) { delete_after = false; }
}



Al ser un desarrollador de C ++ por mucho tiempo (Rookie to web development :)), cuando me encontré por primera vez con esta situación, hice la asignación de parámetros en la definición de la función, como se menciona en la pregunta, de la siguiente manera.

function myfunc(a,b=10)

Pero ten en cuenta que no funciona de manera consistente en todos los navegadores. Para mí, funcionó en Chrome en mi escritorio, pero no funcionó en Chrome en Android. Opción más segura, como muchos han mencionado anteriormente es -

    function myfunc(a,b)
    {
    if (typeof(b)==='undefined') b = 10;
......
    }

La intención de esta respuesta no es repetir las mismas soluciones, lo que otros ya han mencionado, sino informar que la asignación de parámetros en la definición de la función puede funcionar en algunos buscadores, pero no confíe en ello.




Como una actualización ... con ECMAScript 6 puede FINALMENTE establecer valores predeterminados en las declaraciones de parámetros de funciones de esta manera:

function f (x, y = 7, z = 42) {
  return x + y + z
}

f(1) === 50

Según lo mencionado por - http://es6-features.org/#DefaultParameterValues




Para cualquier persona interesada en que su código funcione en Microsoft Edge, no use valores predeterminados en los parámetros de la función.

function read_file(file, delete_after = false) {
    #code
}

En ese ejemplo, Edge arrojará un error "Esperando") '"

Para evitar este uso

function read_file(file, delete_after) {
  if(delete_after == undefined)
  {
    delete_after = false;
  }
  #code
}

A partir del 08 de agosto de 2016, esto sigue siendo un problema




Recomiendo mucho cuidado al usar valores de parámetros por defecto en javascript. A menudo crea errores cuando se usa junto con funciones de orden superior como forEach , map y reduce . Por ejemplo, considere esta línea de código:

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

parseInt tiene una function parseInt(s, [ segundo parámetro opcional function parseInt(s, [ radix =10]) pero map llama a parseInt con tres argumentos: ( elemento , índice y matriz ).

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

En su caso, le sugiero que escriba su función deleteFile de la siguiente manera:

// 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 = false } = options || {}; // if null
  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);

La ejecución del fragmento anterior ilustra los peligros que acechan detrás de los valores de argumento predeterminados para los parámetros no utilizados.




Según la sintaxis

function [name]([param1[ = defaultValue1 ][, ..., paramN[ = defaultValueN ]]]) {
   statements
}

puede definir el valor predeterminado de los parámetros formales. y también verifique el valor indefinido mediante el uso de la función typeof .




Sí, esto funcionará en Javascript. También puedes hacer eso:

function func(a=10,b=20)
{
    alert (a+' and '+b);
}

func(); // Result: 10 and 20

func(12); // Result: 12 and 20

func(22,25); // Result: 22 and 25