---
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 = () =&gt; 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>