--- title: Parámetros predeterminados slug: Web/JavaScript/Reference/Functions/Default_parameters tags: - Característica del lenguaje - ECMAScript 2015 - Funciones - JavaScript translation_of: Web/JavaScript/Reference/Functions/Default_parameters original_slug: Web/JavaScript/Referencia/Funciones/Parametros_por_defecto --- <div>{{jsSidebar("Functions", "Funciones")}}</div> <p><span class="seoSummary"><strong>Parámetros predeterminados de función</strong> permiten que los parámetros con nombre se inicien con valores predeterminados si no se pasa ningún valor o <code>undefined</code>.</span></p> <div>{{EmbedInteractiveExample("pages/js/functions-default.html")}}</div> <p class="hidden">La fuente de este ejemplo interactivo se almacena en un repositorio de GitHub. Si deseas contribuir al proyecto de ejemplos interactivos, clona <a href="https://github.com/mdn/interactive-examples">https://github.com/mdn/interactive-examples</a> y envíanos una solicitud de extracción.</p> <h2 id="Sintaxis">Sintaxis</h2> <pre class="syntaxbox notranslate">function [<var>name</var>]([<var>param1</var>[ = <var>defaultValue1</var> ][, ..., <var>paramN</var>[ = <var>defaultValueN</var> ]]]) { <var>statements</var> } </pre> <h2 id="Descripción">Descripción</h2> <p>En JavaScript, los parámetros de función están predeterminados en {{jsxref("undefined")}}. Sin embargo, a menudo es útil establecer un valor predeterminado diferente. Aquí es donde los parámetros predeterminados pueden ayudar.</p> <p>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 eran <code>undefined</code>.</p> <p>En el siguiente ejemplo, si no se proporciona ningún valor para <code><var>b</var></code> cuando se llama a <code>multiply</code>, el valor de <code><var>b</var></code> sería <code>undefined</code> al evaluar <code><var>a</var> * <var>b</var></code> y <code>multiply</code> devolvería <code>NaN</code>.</p> <pre class="brush: js notranslate">function multiply(a, b) { return a * b } multiply(5, 2) // 10 multiply(5) // NaN ! </pre> <p>Para protegerte contra esto, usarías algo como la segunda línea, donde <code><var>b</var></code> se establece en <code>1</code> si llamas a <code>multiply</code> con un solo argumento:</p> <pre class="brush: js notranslate">function multiply(a, b) { b = (typeof b !== 'undefined') ? b : 1 return a * b } multiply(5, 2) // 10 multiply(5) // 5 </pre> <p>Con los parámetros predeterminados en ES2015, las comprobaciones en el cuerpo de la función ya no son necesarias. Ahora, puedes asignar <code>1</code> como valor predeterminado para <code><var>b</var></code> en el encabezado de la función:</p> <pre class="brush: js notranslate">function multiply(a, b = 1) { return a * b } multiply(5, 2) // 10 multiply(5) // 5 multiply(5, undefined) // 5 </pre> <h2 id="Ejemplos">Ejemplos</h2> <h3 id="Pasar_undefined_vs._otros_valores_falsos">Pasar <code>undefined</code> vs. otros valores falsos</h3> <p>En la segunda llamada de este ejemplo, incluso si el primer argumento se establece explícitamente en <code>undefined</code> (aunque no <code>null</code> u otros valores {{Glossary("falsy", "falsos", "", 1)}} , el valor del argumento <code><var>num</var></code> sigue siendo el predeterminado.</p> <pre class="brush: js notranslate">function test(num = 1) { console.log(typeof num) } test() // 'number' (num se establece en 1) test(undefined) // 'number' (num se establece en 1 también) // prueba con otros valores falsos: test('') // 'string' (num se establece en '') test(null) // 'object' (num se establece en null) </pre> <h3 id="Evaluado_en_el_momento_de_la_llamada">Evaluado en el momento de la llamada</h3> <p>El argumento predeterminado se evalúa en el <em>momento de la llamada</em>. Entonces, a diferencia de (por ejemplo) Python, se crea un nuevo objeto cada vez que se llama a la función.</p> <pre class="brush: js notranslate">function append(value, array = []) { array.push(value) return array } append(1) // [1] append(2) // [2], no [1, 2] </pre> <p>Esto incluso se aplica a funciones y variables:</p> <pre class="brush: js notranslate">function callSomething(thing = something()) { return thing } let numberOfTimesCalled = 0 function something() { numberOfTimesCalled += 1 return numberOfTimesCalled } callSomething() // 1 callSomething() // 2 </pre> <h3 id="Los_parámetros_anteriores_están_disponibles_para_los_parámetros_predeterminados_posteriores">Los parámetros anteriores están disponibles para los parámetros predeterminados posteriores</h3> <p>Los parámetros definidos anteriormente (a la izquierda) están disponibles para los parámetros predeterminados posteriores:</p> <pre class="brush: js notranslate">function greet(name, greeting, message = greeting + ' ' + name) { return [name, greeting, message] } greet('David', 'Hi') // ["David", "Hi", "Hi David"] greet('David', 'Hi', 'Happy Birthday!') // ["David", "Hi", "Happy Birthday!"] </pre> <p>Esta funcionalidad se puede aproximar de esta manera, lo que demuestra cuántos casos extremos se manejan:</p> <pre class="brush: js notranslate">function go() { return ':P' } function withDefaults(a, b = 5, c = b, d = go(), e = this, f = arguments, g = this.value) { return [a, b, c, d, e, f, g] } function withoutDefaults(a, b, c, d, e, f, g) { switch (arguments.length) { case 0: a; case 1: b = 5; case 2: c = b; case 3: d = go(); case 4: e = this; case 5: f = arguments; case 6: g = this.value; default: } return [a, b, c, d, e, f, g]; } withDefaults.call({value: '=^_^='}); // [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] withoutDefaults.call({value: '=^_^='}); // [undefined, 5, 5, ":P", {value:"=^_^="}, arguments, "=^_^="] </pre> <h3 id="Efectos_de_el_ámbito">Efectos de el ámbito</h3> <p>Si se definen parámetros predeterminados para uno o más parámetros, se crea un <a href="https://tc39.es/ecma262/#sec-functiondeclarationinstantiation">segundo ámbito</a> (registro de entorno), específicamente para los identificadores dentro de la lista de parámetros. Este ámbito es padre del ámbito creado para el cuerpo de la función.</p> <p>Esto significa que no se puede hacer referencia a las funciones y variables declaradas en el cuerpo de la función desde los iniciadores de parámetros de valor predeterminado; intentar hacerlo arroja un {{jsxref("ReferenceError")}} en tiempo de ejecución.</p> <p>También significa que las variables declaradas dentro del cuerpo de la función usando <code>var</code> enmascararán los parámetros del mismo nombre, en lugar de que el comportamiento habitual de las declaraciones <code>var</code> duplicadas no tenga ningún efecto.</p> <p>La siguiente función arrojará un <code>ReferenceError</code> cuando se invoca, porque el valor del parámetro predeterminado no tiene acceso al ámbito secundario del cuerpo de la función:</p> <pre class="brush: js example-bad notranslate">function f(a = go()) { // Lanza un `ReferenceError` cuando se invoca a `f`. function go() { return ':P' } } </pre> <p>...y esta función imprimirá <code>undefined</code> porque la variable <code>var a</code> se eleva solo a la parte superior del ámbito creado para el cuerpo de la función (y no hasta el ámbito principal creado para la lista de parámetros):</p> <pre class="brush: js example-bad notranslate">function f(a, b = () => console.log(a)) { var a = 1 b() // Imprime `undefined`, porque los valores de los parámetros predeterminados existen en su propio ámbito } </pre> <h3 id="Parámetros_sin_valores_predeterminados_después_de_los_parámetros_predeterminados">Parámetros sin valores predeterminados después de los parámetros predeterminados</h3> <p>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.</p> <pre class="brush: js notranslate">function f(x = 1, y) { return [x, y] } f() // [1, undefined] f(2) // [2, undefined] </pre> <h3 id="Parámetro_desestructurado_con_asignación_de_valor_predeterminado">Parámetro desestructurado con asignación de valor predeterminado</h3> <p>Puedes usar la asignación de valor predeterminado con la notación {{jsxref("Operators/Destructuring_assignment", "la desestructuración", "", 1)}}:</p> <pre class="brush: js notranslate">function f([x, y] = [1, 2], {z: z} = {z: 3}) { return x + y + z } f() // 6</pre> <h2 id="Especificaciones">Especificaciones</h2> <table class="standard-table"> <thead> <tr> <th scope="col">Especificación</th> </tr> </thead> <tbody> <tr> <td>{{SpecName('ESDraft', '#sec-function-definitions', 'Definición de Funciones')}}</td> </tr> </tbody> </table> <h2 id="Compatibilidad_del_navegador">Compatibilidad del navegador</h2> <div> <div class="hidden">La tabla de compatibilidad de esta página se genera a partir de datos estructurados. Si deseas contribuir con los datos, consulta <a href="https://github.com/mdn/browser-compat-data">https://github.com/mdn/browser-compat-data</a> y envíanos una solicitud de extracción.</div> <p>{{Compat("javascript.functions.default_parameters")}}</p> </div> <h2 id="Ve_también">Ve también</h2> <ul> <li><a class="external" href="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values" rel="external" title="http://wiki.ecmascript.org/doku.php?id=harmony:parameter_default_values">Propuesta original en ecmascript.org</a></li> </ul>