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

2516

Me gustaría que una función de JavaScript tenga argumentos opcionales en los que establezco 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

¿Funciona esto en JavaScript?

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

Desde ES6 / ES2015 , los parámetros predeterminados están en la especificación del idioma.

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

simplemente funciona.

Referencia: Parámetros predeterminados - MDN

Default function parameters allow formal parameters to be initialized with default values if no value or undefined is passed.

También puede simular parámetros con nombre predeterminados mediante 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
    ···
}

Para ES2015 ,

Hay muchas formas, 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';
  ...
}
25
  • 224
    También puede encapsularlo como tal: function defaultFor(arg, val) { return typeof arg !== 'undefined' ? arg : val; }y luego puede llamarlo comoa = defaultFor(a, 42); 2 de septiembre de 2012 a las 5:56
  • 7
    @SiPlus y obtuviste errores de referencia adicionales de forma gratuita al intentar usar undefinedobjetos: p Incluso aunque puede funcionar con algunos navegadores y puede ser más rápido, nullsigue siendo un objeto y undefinedes una referencia a un tipo primitivo que está tratando de decir que hay nada aquí, ni siquiera null. Vea aquí, ambos casos en pocas palabras: JavaScript / Reference / Global_Objects / undefined . 3 de noviembre de 2012 a las 1:29
  • 10
    si contrasta la propiedad de un objeto, entonces typeofes redundante. function foo(data) { var bar = data.bar !== undefined ? data.bar : 'default'; }Esto no arrojará errores de referencia y es conciso.
    Dziamid
    17 de mayo de 2013 a las 11:06
  • 12
    Sé que es realmente menor, pero no me gusta cómo está asignando a = ay b = bcuándo 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- ninguna asignación innecesaria y un poco más fácil de leer.
    Daddy32
    9/12/14 a las 15:31
  • 13
    ¿Hay alguna razón para usarlo typeof? Parecería más sencillo de hacer a === undefined. Además, de esa manera obtendría un error de referencia si lo escribiera mal en lugar de undefinedponerlo en una cadena. 21 de mayo de 2015 a las 22:04
615
function read_file(file, delete_after) {
    delete_after = delete_after || "my default here";
    //rest of code
}

Esto se asigna al delete_aftervalor de delete_aftersi no es un valor falsey; de lo contrario, asigna la cadena "my default here". Para obtener más detalles, consulte la encuesta del idioma de Doug Crockford y consulte la sección sobre operadores .

Este enfoque no funciona si se desea pasar de un Falsey- es decir, valor false, null, undefined, 0o "". Si necesita que se pasen valores falsos , deberá usar el método en la respuesta de Tom Ritter .

Cuando se trata de 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 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" }); 
15
  • 118
    Encuentro esto insuficiente, porque puedo querer pasar en falso. 21 de mayo de 2009 a las 20:11
  • 52
    Encuentro que es adecuado para la mayoría de situaciones. 21 de mayo de 2009 a las 20:16
  • 51
    Debido a que no funciona para valores falsos, puede crear una pesadilla de mantenimiento. Un poco de código al que siempre se le han pasado valores verdaderos antes y que falla repentinamente porque se pasa uno falso probablemente debería evitarse cuando haya un enfoque más sólido disponible. 31/10/12 a las 20:34
  • 1
    ¿Cómo es que, en este caso, delete_afterno obtiene el resultado booleano de la expresión delete_after || "my default value"?
    xbonez
    28/11/12 a las 5:56
  • 3
    o, simplemente podría establecer un valor de falsey por defecto, que generalmente es un buen valor predeterminado de todos modos (por ejemplo, falso para bools, cadena vacía para cadenas, 0 para números, etc.), en cuyo caso realmente no importa lo que fue aprobada en. 27 de marzo de 2016 a las 1:33
153

Me parece que algo tan 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');
} 
7
  • 6
    Actualización: si ya está usando underscore.js, lo encuentro aún mejor de 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 util.default(arg, "defaul value")usar su propia utilidad para esta tarea común (p. Ej. ) Si no quiere usar el subrayado, pero la mayoría de las veces termino usando el subrayado tarde o temprano de todos modos, no tiene sentido reinventar la rueda. 15/08/2014 a las 20:12
  • 2
    De hecho, recomiendo este, lo uso y lo llamo "por", que significa "parámetro o"
    user2039981
    21/04/2015 a las 16:59
  • 2
    No diga typeof arg == 'undefined', en su lugar diga arg === undefined 20/10/15 a las 15:06
  • 3
    @OsamaBinLogin lo que dice es correcto para JS actual: la prueba anterior persiste porque en algunos navegadores solía ser posible sobrescribir undefinedcon algún otro valor, lo que hacía que la prueba fallara.
    Alnitak
    16/11/15 a las 11:34
  • 2
    @Alnitak: Todavía es posible anular undefined. Por lo tanto, sigue siendo una buena idea usar typeofy 'undefined'. 14/06/2017 a las 20:27
66

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

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

Esto se establecerá delete_afteren falsesi no está presente o undefined. Puede utilizar funciones de ES6 como esta hoy con transpilers como Babel .

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

6
30

Valores de parámetros predeterminados

Con ES6, puede hacer quizás uno de los modismos más comunes JavaScriptrelacionados con el establecimiento de 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 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 así el x || 11 results in 11, no el pasado directamente en 0. Para solucionar este problema, algunas personas escribirán el cheque de manera 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 sintaxis útil y agradable agregada a partir de ES6para 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 = 11en una declaración de función es más parecido x !== undefined ? x : 11al modismo mucho más comúnx || 11

Expresiones de valor predeterminado

Functionlos valores predeterminados pueden ser más que simples valores como 31; pueden ser cualquier expresión válida, incluso un 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 predeterminado se evalúan de manera perezosa, lo que significa que solo se ejecutan cuando se necesitan, es decir, cuando el argumento de un parámetro se omite o no está definido.

Una expresión de valor predeterminado puede ser incluso 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
dieciséis

esa solución funciona para mí en js:

function read_file(file, delete_after) {
    delete_after = delete_after || false;
    // Code
}
4
  • 4
    ¿Qué pasa si delete_afteres 0o null? No funcionará correctamente para estos casos. 20/12/15 a las 9:33
  • @StephanBijzitter solo sería cierto en algunos casos. Pero si solo desea que los valores predeterminados anulen los valores, esto no funcionó, ¡porque 0 o nulo! === falso.
    Rutrus
    1 de febrero de 2017 a las 10:13
  • @Rutrus: No entiendo nada de lo que acabas de decir. 1 de febrero de 2017 a las 10:21
  • ¿Qué hay de delete_after = delete_after === undefined ? false : delete_after?
    aashah7
    28/04/2017 a las 3:50
12

Recomiendo encarecidamente tener extrema precaución al usar valores de parámetros predeterminados en javascript. A menudo crea errores cuando se utiliza en combinación 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 base de segundo parámetro opcional pero function parseInt(s, [asigna=10]) llamadas parseIntcon tres argumentos: ( elemento , índice y matriz ).

Le sugiero que separe sus parámetros requeridos de sus argumentos 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, todos los parámetros opcionales deben seguir como atributos con nombre de un solo objeto. Si su función toma 4 o más, quizás tenga más sentido proporcionar todos los argumentos a través de los atributos de un único parámetro de objeto.

En su caso, le recomendamos que escriba su función deleteFile como esto: ( 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);

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

3
  • 1
    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 caso de utilizar 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);})
    instead
    26/01/19 a las 17:36
  • Ese es un buen punto. Estaba tratando de evitar el uso de bibliotecas en mi fragmento de código, pero este idioma es bastante complicado en JavaScript puro. Personalmente, usaría el getmétodo de lodash para recuperar deleteAfter. Lanzar una excepción 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 quien llama. El comportamiento final debe seguir el principio de la mínima sorpresa. 26/01/19 a las 18:18
  • Estoy de acuerdo, ese método no debe escribirse de la manera, que llamarlo puede romper su comportamiento. Pero tenga en cuenta que la función es como un modelo y la persona que llama es como un 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 Exception es la mejor manera. Aunque es más complejo. Pero aún así puede evitar que te rasques la cabeza y sigas preguntando ... ¡¿POR QUÉ NO FUNCIONA ?! y luego ... ¡¿POR QUÉ ESTÁ FUNCIONANDO ?!
    instead
    26/01/19 a las 23:52
11

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

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

Como actualización ... con ECMAScript 6, FINALMENTE puede establecer valores predeterminados en declaraciones de parámetros de función de la siguiente manera:

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

f(1) === 50

Como lo hace referencia: http://es6-features.org/#DefaultParameterValues

1
  • 11
    Esta respuesta no es útil porque es un duplicado.
    user
    6 de noviembre de 2015 a las 0:48
9

Siendo un desarrollador de C ++ desde hace mucho tiempo (novato en el desarrollo web :)), 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 tenga en cuenta que no funciona de manera uniforme en todos los navegadores. Para mí, funcionó en Chrome en mi escritorio, pero no funcionó en Chrome en Android. La 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 navegadores, pero no confíe en ella.

2
  • 3
    La asignación dentro de la definición de función tampoco funciona en IE 11, que es la versión más actual de IE para Windows 8.1.
    DiMono
    19 de julio de 2016 a las 2:52
  • 1
    En caso de que alguien se pregunte, function myfunc(a,b=10)es la sintaxis de ES6, hay enlaces a tablas de compatibilidad en otras respuestas. 18 de septiembre de 2016 a las 9:00
8

Para cualquier persona interesada en que el código funcione en Microsoft Edge, no use valores predeterminados en los parámetros de 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 8 de agosto de 2016, esto sigue siendo un problema.

5

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 usando la función typeof .

5
function helloWorld(name, symbol = '!!!') {
    name = name || 'worlds';
    console.log('hello ' + name + symbol);
}

helloWorld(); // hello worlds!!!

helloWorld('john'); // hello john!!!

helloWorld('john', '(>.<)'); // hello john(>.<)

helloWorld('john', undefined); // hello john!!!

helloWorld(undefined, undefined); // hello worlds!!!
5

Use esto si desea usar la última ECMA6sintaxis:

function myFunction(someValue = "This is DEFAULT!") {
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

Se llama default function parameters. Permite que los parámetros formales se inicialicen con valores predeterminados si no se pasa ningún valor o indefinido. NOTA : No funcionará con Internet Explorer o navegadores más antiguos.

Para obtener la máxima compatibilidad posible, utilice esto:

function myFunction(someValue) {
  someValue = (someValue === undefined) ? "This is DEFAULT!" : someValue;
  console.log("someValue --> ", someValue);
}

myFunction("Not A default value") // calling the function without default value
myFunction()  // calling the function with default value

Ambas funciones tienen exactamente el mismo comportamiento ya que cada uno de estos ejemplos se basa en el hecho de que la variable de parámetro será undefinedsi no se pasó ningún valor de parámetro al llamar a esa función.

1
  • NOTA: como dice @BlackBeard, la función (param = valor) NO funcionará con IE. Utilice la versión compatible. 16/11/18 a las 2:31
5

Si está utilizando ES6+, puede establecer los parámetros predeterminados de la siguiente manera:

function test (foo = 1, bar = 2) {
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

Si necesita ES5sintaxis, puede hacerlo de la siguiente manera:

function test(foo, bar) {
  foo = foo || 2;
  bar = bar || 0;
  
  console.log(foo, bar);
}

test(5); // foo gets overwritten, bar remains default parameter

En la sintaxis anterior ORse utiliza el operador. El ORoperador siempre devuelve el primer valor si se puede convertir, truesi no, devuelve el valor del lado derecho. Cuando se llama a la función sin un argumento correspondiente, el motor JS barestablece la variable de parámetro ( en nuestro ejemplo) undefined. undefinedLuego se convierte en falso y, por lo tanto, el ORoperador devuelve el valor 0.

5

ES6: Como ya se mencionó en la mayoría de las respuestas, en ES6, simplemente puede inicializar un parámetro junto con un valor.


ES5: La mayoría de las respuestas dadas no son lo suficientemente buenas para mí porque hay ocasiones en las que tengo que pasar valores falsos como 0, nully undefineda una función. Para determinar si un parámetro no está definido porque ese es el valor que pasé en lugar de indefinido debido a que no se ha definido en absoluto, hago esto:

function foo (param1, param2) {
   param1 = arguments.length >= 1 ? param1 : "default1";
   param2 = arguments.length >= 2 ? param2 : "default2";
}
4

function throwIfNoValue() {
throw new Error('Missing argument');
}
function foo(argValue = throwIfNoValue()) {
return argValue ;
}

Aquí foo () es una función que tiene un parámetro llamado argValue. Si no pasamos nada en la llamada a la función aquí, entonces se llamará a la función throwIfNoValue () y el resultado devuelto se asignará al único argumento argValue. Así es como se puede utilizar una llamada a función como parámetro predeterminado. Lo que hace que el código sea más simplificado y legible.

Este ejemplo ha sido tomado de aquí.

4

Sí, el uso de parámetros predeterminados es totalmente compatible con ES6 :

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

o

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

pero antes en ES5 , fácilmente podría hacer esto:

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

Lo que significa que si el valor está allí, use el valor; de lo contrario, use el segundo valor después de la ||operación que hace lo mismo ...

Nota: también hay una gran diferencia entre aquellos si pasa un valor a ES6, incluso si el valor es falso, que se reemplazará con un nuevo valor, algo como nullo ""... pero ES5 solo se reemplazará si solo el valor pasado es la verdad, eso es porque la forma de ||trabajar ...

3

Si por alguna razón usted no en la ES6 y se utiliza lodashaquí es una forma concisa a los parámetros por defecto de función a través de _.defaultTométodo:

var fn = function(a, b) {
  a = _.defaultTo(a, 'Hi')
  b = _.defaultTo(b, 'Mom!')

  console.log(a, b)
}

fn()                 // Hi Mom!
fn(undefined, null)  // Hi Mom!
fn(NaN, NaN)         // Hi Mom!
fn(1)                // 1 "Mom!"
fn(null, 2)          // Hi 2
fn(false, false)     // false false
fn(0, 2)             // 0 2
<script src="https://cdnjs.cloudflare.com/ajax/libs/lodash.js/4.17.11/lodash.min.js"></script>

Que establecerá el valor predeterminado si el valor actual es NaN , nulo o indefinido

3

Sonidos del futuro

En el futuro, podrá "difundir" un objeto a otro (¡actualmente a partir de 2019 NO es compatible con Edge !) - demostración de cómo usar eso para obtener buenas opciones predeterminadas independientemente del orden:

function test(options) {
    var options = {
       // defaults
       url: 'defaultURL',
       some: 'somethingDefault',
       // override with input options
       ...options
    };
    
    var body = document.getElementsByTagName('body')[0];
    body.innerHTML += '<br>' + options.url + ' : ' + options.some;
}
test();
test({});
test({url:'myURL'});
test({some:'somethingOfMine'});
test({url:'overrideURL', some:'andSomething'});
test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

Referencia de MDN: https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Operators/Spread_syntax

... mientras tanto, lo que SÍ admite Edge es Object.assign () (IE no lo hace, pero realmente espero que podamos dejar IE atrás :))

Del mismo modo, podrías hacer

    function test(options) {
        var options = Object.assign({
           // defaults
           url: 'defaultURL',
           some: 'somethingDefault',
        }, options); // override with input options
        
        var body = document.getElementsByTagName('body')[0];
        body.innerHTML += '<br>' + options.url + ' : ' + options.some;
    }
    test();
    test({});
    test({url:'myURL'});
    test({some:'somethingOfMine'});
    test({url:'overrideURL', some:'andSomething'});
    test({url:'overrideURL', some:'andSomething', extra:'noProblem'});

EDITAR: Debido a los comentarios sobre las constopciones, el problema con el uso de opciones constantes en el resto de la función no es que no pueda hacer eso, es solo que no puede usar la variable constante en su propia declaración, tendría para ajustar el nombre de la entrada a algo como

function test(input_options){
   const options = {
     // defaults
     someKey:    'someDefaultValue',
     anotherKey: 'anotherDefaultValue',

     // merge-in input options
     ...input_options
   };

   // from now on use options with no problem
}
5
  • El problema es que normalmente nunca querrás hacer eso, ya que esto reasignará opciones que ya están definidas, pero puedes usarlas con otra var que sería legítima. 13/12/19 a las 13:29
  • function test (options) {/ * Las opciones están definidas y arrojará un error si usa const options = {} ahora * /} 13/12/19 a las 14:19
  • no, no es global cuando crea una función y pasa como opciones de nombre de argumento, luego dentro de las opciones de la función se define dentro de la función (opt) {} opt está definido, no puede usar const opt ​​dentro de esa función, entonces esto es malo porque lo hace reasignación de variables si lo hace con frecuencia y parece que su patrón general es un problema 14/12/19 a las 7:03
  • @ google-frank-dspeed ah, ¿quieres decir que no puedes hacer function(opt){ const opt = /*some merging*/; }? Eso seguramente no funcionará porque usaría la constvariable antes de que se declarara , tendría que ajustarla.function test(input_opt){ const opt = { someKey: 'someDefaultValue', ...input_opt} } 16 dic 2019 a las 12:45
  • @ google-frank-dspeed de todos modos, más gente nueva probablemente se preguntará acerca de esto, así que agregué el código de cómo editar :) así que gracias por señalarlo a los demás :) 16 dic 2019 a las 13:00
2

Solo para mostrar mis habilidades también (risas), la función anterior se puede escribir incluso sin tener los argumentos nombrados como se muestra a continuación:

ES5 y superior

function foo() {
    a = typeof arguments[0] !== 'undefined' ? a : 42;
    b = typeof arguments[1] !== 'undefined' ? b : 'default_b';
    ...
}

ES6 y superior

function foo(...rest) {
    a = typeof rest[0] !== 'undefined' ? a : 42;
    b = typeof rest[1] !== 'undefined' ? b : 'default_b';
    ...
}
1

Sí, esto se conoce como parámetro predeterminado

Los parámetros de función predeterminados permiten que los parámetros formales se inicialicen con valores predeterminados si no se pasa ningún valor o si se pasa indefinido.

Sintaxis:

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

Descripción:

Los parámetros de las funciones están predeterminados como indefinidos Sin embargo, en situaciones puede ser útil establecer un valor predeterminado diferente. Aquí es donde los parámetros predeterminados pueden ayudar.

En el pasado, la estrategia general para establecer valores predeterminados era probar los valores de los parámetros en el cuerpo de la función y asignar un valor si no estaban definidos. Si no se proporciona ningún valor en la llamada, su valor sería indefinido. Debería establecer una verificación condicional para asegurarse de que el parámetro no esté indefinido

Con los parámetros predeterminados en ES2015, la verificación en el cuerpo de la función ya no es necesaria. Ahora puede simplemente poner un valor predeterminado en el encabezado de la función.

Ejemplo de las diferencias:

// OLD METHOD
function multiply(a, b) {
  b = (typeof b !== 'undefined') ?  b : 1;
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5


// NEW METHOD
function multiply(a, b = 1) {
  return a * b;
}

multiply(5, 2); // 10
multiply(5, 1); // 5
multiply(5);    // 5

Diferentes ejemplos de sintaxis:

Relleno indefinido frente a otros valores falsos:

Incluso si el valor se establece explícitamente al llamar, el valor del argumento num es el predeterminado.

function test(num = 1) {
  console.log(typeof num);
}

test();          // 'number' (num is set to 1)
test(undefined); // 'number' (num is set to 1 too)

// test with other falsy values:
test('');        // 'string' (num is set to '')
test(null);      // 'object' (num is set to null)

Evaluado al momento de la llamada:

El argumento predeterminado se evalúa en el momento de la llamada, por lo que, a diferencia de otros lenguajes, se crea un nuevo objeto cada vez que se llama a la función.

function append(value, array = []) {
  array.push(value);
  return array;
}

append(1); //[1]
append(2); //[2], not [1, 2]


// This even applies to functions and variables
function callSomething(thing = something()) {
 return thing;
}

function something() {
  return 'sth';
}

callSomething();  //sth

Los parámetros predeterminados están disponibles para los parámetros predeterminados posteriores:

Los parámetros ya encontrados están disponibles para los parámetros predeterminados posteriores

function singularAutoPlural(singular, plural = singular + 's',
                        rallyingCry = plural + ' ATTACK!!!') {
  return [singular, plural, rallyingCry];
}

//["Gecko","Geckos", "Geckos ATTACK!!!"]
singularAutoPlural('Gecko');

//["Fox","Foxes", "Foxes ATTACK!!!"]
singularAutoPlural('Fox', 'Foxes');

//["Deer", "Deer", "Deer ... change."]
singularAutoPlural('Deer', 'Deer', 'Deer peaceably and respectfully \ petition the government for positive change.')

Funciones definidas dentro del cuerpo de la función:

Introducido en Gecko 33 (Firefox 33 / Thunderbird 33 / SeaMonkey 2.30). Las funciones declaradas en el cuerpo de la función no se pueden hacer referencia dentro de los parámetros predeterminados y arrojan un ReferenceError (actualmente un TypeError en SpiderMonkey, consulte el error 1022967). Los parámetros predeterminados siempre se ejecutan primero, las declaraciones de función dentro del cuerpo de la función se evalúan después.

// Doesn't work! Throws ReferenceError.
function f(a = go()) {
  function go() { return ':P'; }
}

Parámetros sin valores predeterminados después de los parámetros predeterminados:

Antes de Gecko 26 (Firefox 26 / Thunderbird 26 / SeaMonkey 2.23 / Firefox OS 1.2), el siguiente código generaba un SyntaxError. Esto se ha corregido en el error 777060 y funciona como se esperaba en versiones posteriores. Los parámetros aún se establecen de izquierda a derecha, sobrescribiendo los parámetros predeterminados incluso si hay parámetros posteriores sin valores predeterminados.

function f(x = 1, y) {
  return [x, y];
}

f(); // [1, undefined]
f(2); // [2, undefined]

Parámetro desestructurado con asignación de valor por defecto:

Puede utilizar la asignación de valor predeterminada con la notación de asignación de desestructuración

function f([x, y] = [1, 2], {z: z} = {z: 3}) {
  return x + y + z;
}

f(); // 6
1

He notado algunas respuestas que mencionan que el uso de parámetros predeterminados no es portátil para otros navegadores, pero es justo señalar que puede usar transpiladores como Babel para convertir su código en la sintaxis ES5 para navegadores que tienen soporte limitado para JS moderno. características.

Así que esto:

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

se transpilaría así (pruébelo en Babel REPL -> https://babeljs.io/repl/ ):

"use strict";

function read_file(file) {

  var delete_after =
    arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : false;
  
  //Code...

}

Por supuesto, si no tiene la intención de usar la transpilación, entonces establecer parámetros predeterminados en el cuerpo de la función, como otros han demostrado, también está perfectamente bien.

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

El siguiente código puede funcionar en esta situación, incluido ECMAScript 6 (ES6), así como versiones anteriores.

function read_file(file, delete_after) {
    if(delete_after == undefined)
        delete_after = false;//default value

    console.log('delete_after =',delete_after);
}
read_file('text1.txt',true);
read_file('text2.txt');

como valor predeterminado en los idiomas funciona cuando el valor del parámetro de la función se omite al llamar, en JavaScript se asigna a indefinido . Este enfoque no parece atractivo mediante programación, pero tiene compatibilidad con versiones anteriores .

0

Solo un enfoque diferente para establecer parámetros predeterminados es usar un mapa de objetos de argumentos, en lugar de argumentos directamente. Por ejemplo,

const defaultConfig = {
 category: 'Animals',
 legs: 4
};

function checkOrganism(props) {
 const category = props.category || defaultConfig.category;
 const legs = props.legs || defaultConfig.legs;
}

De esta manera, es fácil extender los argumentos y no preocuparse por la falta de coincidencia de la longitud de los argumentos.

0

Sí - prueba:

function read_file(file, delete_after = false) {
  // Code
  console.log({file,delete_after});
}



// TEST
read_file("A");
read_file("B",true);
read_file("C",false);
0
export const getfilesize = (bytes, decimals = 2) => {
    if (bytes === 0){ 
        return '0 Bytes';
    }else{
        const k = 1024;
        const dm = decimals < 0 ? 0 : decimals;
        const sizes = ['Bytes', 'KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'];
        const i = Math.floor(Math.log(bytes) / Math.log(k));
        return parseFloat((bytes / Math.pow(k, i)).toFixed(dm)) + ' ' + sizes[i];

    }
}
-1

La respuesta es sí. De hecho, hay muchos idiomas que admiten parámetros predeterminados. Python es uno de ellos:

def(a, enter="Hello"):
   print(a+enter)

Aunque este es el código de Python 3 debido a los paréntesis, los parámetros predeterminados en las funciones también funcionan en JS.

Por ejemplo, y en tu caso:

function read_file(file, deleteAfter=false){
  console.log(deleteAfter);
}

read_file("test.txt");

Pero a veces realmente no necesitas los parámetros predeterminados.

Puede definir la variable justo después del inicio de la función, así:

function read_file(file){
  var deleteAfter = false;
  console.log(deleteAfter);
}

read_file("test.txt");

En mis dos ejemplos, devuelve lo mismo. Pero a veces pueden resultar útiles, como en proyectos muy avanzados.

Entonces, en conclusión, los valores de parámetros predeterminados se pueden usar en JS. Pero es casi lo mismo que definir una variable justo después del inicio de la función. Sin embargo, a veces siguen siendo muy útiles. Como habrá notado, los valores de los parámetros predeterminados toman 1 línea menos de código que la forma estándar que define el parámetro justo después del inicio de la función.

EDITAR: ¡ Y esto es súper importante! Esto no funcionará en IE. Ver documentación . Entonces, con IE tienes que usar el método "definir variable en la parte superior de la función". Los parámetros predeterminados no funcionarán en IE.

-3

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
1