diff options
Diffstat (limited to 'files/es/web/javascript/referencia/sentencias/let/index.html')
-rw-r--r-- | files/es/web/javascript/referencia/sentencias/let/index.html | 393 |
1 files changed, 393 insertions, 0 deletions
diff --git a/files/es/web/javascript/referencia/sentencias/let/index.html b/files/es/web/javascript/referencia/sentencias/let/index.html new file mode 100644 index 0000000000..8c450b37d4 --- /dev/null +++ b/files/es/web/javascript/referencia/sentencias/let/index.html @@ -0,0 +1,393 @@ +--- +title: let +slug: Web/JavaScript/Referencia/Sentencias/let +tags: + - Característica del lenguaje + - Declaración de variable + - ECMAScript 2015 + - JavaScript + - Variables + - let + - sentencias +translation_of: Web/JavaScript/Reference/Statements/let +--- +<div>{{jsSidebar("Statements")}}</div> + +<p>La instrucción <strong><code>let</code></strong> declara una variable de alcance local con ámbito de bloque<font><font>(</font></font><a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/block">block </a>scope<font><font>)</font></font>, la cual, opcionalmente, puede ser inicializada con algún valor.</p> + +<div class="warning"> +<p class="p1">La palabra reservada <strong><code><span class="s1">let </span></code></strong>en Mozilla Firefox 44 y anteriores, está solo disponible para bloques de código en HTML que esten envueltos en una etiqueta <code><span class="s1"><script type="application/javascript;version=1.7"></span></code> (o de una version mayor). Las etiquetas <a href="https://developer.mozilla.org/en-US/docs/XUL">XUL</a> tienen acceso a esas características sin necesidad de dicho bloque. Es necesario tomar en cuenta que esta es una característica <s>no estándar</s> <u>que ya se ha hecho actualmente estándar</u>, <s>esto</s> <u>pero</u> puede crear conflictos con otros navegadores<u>, ya que fue una característica no estándar.</u></p> +</div> + +<h2 id="Sintaxis">Sintaxis</h2> + +<pre class="syntaxbox notranslate">let var1 [= valor1] [, var2 [= valor2]] [, ..., varN [= valorN]];</pre> + +<h3 id="Parámetros">Parámetros</h3> + +<dl> + <dt><code>var1</code>, <code>var2</code>, …, <code>varN</code></dt> + <dd>Los nombres de la variable o las variables a declarar. Cada una de ellas debe ser un identificador legal de JavaScript</dd> + <dt><code>value1</code>, <code>value2</code>, …, <code>valueN</code></dt> + <dd>Por cada una de las variables declaradas puedes, opcionalmente, especificar su valor inicial como una expresión legal JavaScript.</dd> +</dl> + +<h2 id="Descripción">Descripción</h2> + +<p><strong><code>let</code> </strong>te permite declarar variables limitando su alcance (<em>scope</em>) al bloque, declaración, o expresión donde se está usando.a diferencia de la palabra clave <code>var</code> la cual define una variable global o local en una función sin importar el ámbito del bloque. La otra diferencia entre <code>var</code> y <code>let</code> <span class="VIiyi" lang="es"><span class="ChMk0b JLqJ4b"><span>es que este último se inicializa a un valor sólo cuando un analizador lo evalúa (ver abajo).</span></span></span></p> + +<p>Al igual que <code>const</code>, <code>let </code>no crea propiedades del objeto se declara globalmente (en el alcance más alto).</p> + +<h3 id="Alcance_scope_a_nivel_de_bloque_con_let">Alcance (<em>scope</em>) a nivel de bloque con <code>let</code></h3> + +<p>Usar la palabra reservada <code>let</code> para definir variables dentro de un bloque.</p> + +<pre class="brush:js notranslate">if (x > y) { + let gamma = 12.7 + y; + i = gamma * x; +} +</pre> + +<p>Es posible usar definiciones <code>let</code> para asociar código en extensiones con un pseudo-espacio-de-nombre (pseudo-namespace). (Ver <a href="/en-US/docs/Security_best_practices_in_extensions" title="en-US/docs/Security_best_practices_in_extensions">Mejores prácticas de seguridad en extensiones</a>.)</p> + +<pre class="brush:js notranslate">let Cc = Components.classes, Ci = Components.interfaces; +</pre> + +<p><code>let</code> puede ser útil para escribir código más limpio cuando usamos funciones internas.</p> + +<pre class="brush:js notranslate">var list = document.getElementById("list"); + +for (var i = 1; i <= 5; i++) { + var item = document.createElement("LI"); + item.appendChild(document.createTextNode("Item " + i)); + + let j = i; + item.onclick = function (ev) { + console.log("Item " + j + " is clicked."); + }; + list.appendChild(item); +} +</pre> + +<p>El ejemplo anterior trabaja como se espera porque las cinco instancias de la función (anónima) interna hacen referencia a cinco diferentes instancias de la variable <code>j</code>. Nótese que esto no funcionaría como se espera si reemplazamos <code>let</code> con <code>var</code> o si removemos la variable <code>j</code> y simplemente usamos la variable <code>i</code> dentro de la función interna.</p> + +<h4 id="Reglas_de_alcance">Reglas de alcance</h4> + +<p>Variables declaradas por <code>let</code> tienen por alcance el bloque en el que se han definido, así mismo, como en cualquier bloque interno. De esta manera, <code>let</code> trabaja muy parecido a <code>var</code>. La más notable diferencia es que el alcance de una variable <code>var</code> es la función contenedora:</p> + +<pre class="brush:js notranslate">function varTest() { + var x = 31; + if (true) { + var x = 71; // ¡misma variable! + console.log(x); // 71 + } + console.log(x); // 71 +} + +function letTest() { + let x = 31; + if (true) { + let x = 71; // variable diferente + console.log(x); // 71 + } + console.log(x); // 31 +} +// llamamos a las funciones +varTest(); +letTest(); +</pre> + +<p>En el nivel superior de un programa y funciones, <code>let</code> , a diferencia de <code>var</code>, <strong>no crea</strong> una propiedad en el objeto global, por ejemplo:</p> + +<pre class="brush:js notranslate">var x = 'global'; +let y = 'global'; +console.log(this.x); // "global" +console.log(this.y); // undefined +</pre> + +<p>La salida de este código desplegaría "global" una vez.</p> + +<h3 id="Zona_muerta_temporal_y_errores_con_let">Zona muerta temporal y errores con <code>let<a id="muerta" name="muerta"></a></code></h3> + +<p>La <strong>redeclaración</strong> de la misma variable bajo un mismo <font><font><a href="https://www.ecma-international.org/ecma-262/6.0/#sec-lexical-environments">ámbito léxico</a> </font></font>terminaría en un error de tipo <code><a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Objetos_globales/SyntaxError" title="SyntaxError">SyntaxError</a></code>. Esto también es <strong>extensible</strong> si usamos <code>var</code> dentro del <font><font>ámbito léxico</font></font>. Esto nos salvaguarda de redeclarar una variable accidentalmente y que no era posible solo con <code>var.</code></p> + +<pre class="brush: js notranslate">if (x) { + let foo; + let foo; // Terminamos con un SyntaxError. +} +if (x) { + let foo; + var foo; // Terminamos con un SyntaxError. +} +</pre> + +<p>En ECMAScript 2015, <code>let</code> <a href="https://developer.mozilla.org/es/docs/Web/JavaScript/Referencia/Sentencias/var#Description">no eleva</a> la variable a la parte superior del bloque. Si se hace una referencia a la variable declarada con <code>let</code> (<code>let foo</code>) antes de su declaración, terminaríamos con un error de tipo <code><a href="/en-US/docs/JavaScript/Reference/Global_Objects/ReferenceError" title="TypeError">ReferenceError</a> </code>(al contrario de la variable declarada con <code>var</code>, que tendrá el valor <code>undefined</code>), esto porque la variables vive en una "zona muerta temporal" desde el inicio del bloque hasta que la declaración ha sido procesada.</p> + +<pre class="notranslate"><code>function do_something() { + console.log(bar); // undefined + console.log(foo); // ReferenceError: foo </code>no está definido<code> + var bar = 1; + let foo = 2; +}</code></pre> + +<p>Es posible encontrar errores en bloques de control <a href="/en-US/docs/JavaScript/Reference/Statements/switch" title="switch"><code>switch</code></a> debido a que solamente existe un block subyacente.</p> + +<pre class="brush: js notranslate">switch (x) { + case 0: + let foo; + break; + + case 1: + let foo; // Terminamos con un error de tipo SyntaxError. + // esto debido a la redeclaracion + break; +}</pre> + +<h3 id="Otro_ejemplo_de_zona_muerta_temporal_combinada_con_ámbito_léxico"><font><font>Otro ejemplo de zona muerta temporal combinada con <a href="https://www.ecma-international.org/ecma-262/6.0/#sec-lexical-environments">ámbito léxico</a></font></font></h3> + +<p>Debido al alcance léxico, el identificador <code>num</code> dentro de la expresión (<code>num + 55</code>) se evalúa como <code>num</code> del bloque <code>if</code>, y no como la variable <code>num</code> con el valor 33 que esta por encima</p> + +<p>En esa misma línea, el <code>num </code>del bloque <code>if</code> ya se ha creado en el ámbito léxico, pero aún no ha alcanzado (y <strong>terminado</strong>) su inicialización (que es parte de la propia declaración): todavía está en la zona muerta temporal.</p> + +<pre class="notranslate"><code>function prueba(){ + var num = 33; + if (true) { + let num = (num + 55);</code>//ReferenceError: no se puede acceder a la declaración léxica `num'antes de la inicialización <code> + } +} +prueba();</code> +</pre> + +<h2 id="Ejemplos">Ejemplos</h2> + +<h3 id="let_vs_var"><code>let</code> vs <code>var</code></h3> + +<p>Cuando usamos <code>let</code> dentro de un bloque, podemos limitar el alcance de la variable a dicho bloque. Notemos la diferencia con <code>var</code>, cuyo alcance reside dentro de la función donde ha sido declarada la variable.</p> + +<pre class="brush: js notranslate">var a = 5; +var b = 10; + +if (a === 5) { + let a = 4; // El alcance es dentro del bloque if + var b = 1; // El alcance es global + + console.log(a); // 4 + console.log(b); // 1 +} + +console.log(a); // 5 +console.log(b); // 1</pre> + +<h3 id="let_en_bucles"><code>let</code> en bucles</h3> + +<p>Es posible usar la palabra reservada <code>let</code> para enlazar variables con alcance local dentro del alcance de un bucle en lugar de usar una variable global (definida usando <code>var</code>) para dicho propósito.</p> + +<pre class="brush: js notranslate">for (let i = 0; i<10; i++) { + console.log(i); // 0, 1, 2, 3, 4 ... 9 +} + +console.log(i); // ReferenceError: i is not defined +</pre> + +<h2 id="Extensiones_let_no-estandar">Extensiones <code>let</code> no-estandar</h2> + +<h3 id="Bloques_let">Bloques<code> let</code></h3> + +<div class="warning"> +<p>La <strong>sintaxis del bloque y expresion</strong> <code>let</code> es no-estandar y sera deshechado en un futuro. ¡No deben ser usados! ver <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1023609" rel="noopener" title="FIXED: Remove SpiderMonkey support for let expressions">error 1023609</a> y <a href="https://bugzilla.mozilla.org/show_bug.cgi?id=1167029" rel="noopener" title="FIXED: Remove SpiderMonkey support for let blocks">error 1167029</a> para mas detalles.</p> +</div> + +<p>Un <strong>bloque <code>let</code></strong> provee una manera de asociar valores con variables dentro del alcance de un bloque sin afectar el valor de variables con nombre similar fuera del bloque.</p> + +<h4 id="Sintaxis_2">Sintaxis</h4> + +<pre class="syntaxbox notranslate">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) {declaración};</pre> + +<h4 id="Descripción_2">Descripción</h4> + +<p>El bloque <code>let</code> provee alcance local para las variables. Funciona enlazando cero o más variables en el alcance léxico de un solo bloque de código; de otra manera, es exactamente lo mismo que una declaración de bloque. Hay que notar particularmente que el alcance de una variable declarada dentro de un bloque <code>let</code> usando var es equivalente a declarar esa variable fuera del bloque <code>let</code>; dicha variable aún tiene alcance dentro de la función. Al usar la sintaxis de bloque <code>let</code>, los paréntesis siguientes a <code>let</code> son requeridos. Una falla al incluir dichos paréntesis resultará en un error de sintaxis.</p> + +<h4 id="Ejemplo">Ejemplo</h4> + +<pre class="brush:js notranslate">var x = 5; +var y = 0; + +let (x = x+10, y = 12) { + console.log(x+y); // 27 +} + +console.log(x + y); // 5 +</pre> + +<p>Las reglas para el bloque de código son las mismas que para cualquier otro bloque de código en JavaScript. Es posible tener sus propias variables locales usando declaraciones <code>let</code> en dicho bloque.</p> + +<h4 id="Reglas_de_alcance_2">Reglas de alcance</h4> + +<p>El alcance de las variables definidas usando <code>let</code> es el mismo bloque <code>let</code>, así como cualquier bloque interno contenido dentro de el bloque, a menos que esos bloques internos definan variables con el mismo nombre.</p> + +<h3 id="expresiones_let">expresiones <code>let</code></h3> + +<div class="warning"> +<p><code>Soporte de <strong>expresiones</strong> let</code> ha sido removido en Gecko 41 ({{bug(1023609)}}).</p> +</div> + +<p>Una <strong>expresion <code>let</code></strong> permite establecer variables con alcance dentro de una expresión.</p> + +<h4 id="Sintaxis_3">Sintaxis</h4> + +<pre class="syntaxbox notranslate">let (var1 [= value1] [, var2 [= value2]] [, ..., varN [= valueN]]) expression;</pre> + +<h4 id="Ejemplo_2">Ejemplo</h4> + +<p>Podemos usar <code>let</code> para establecer variables que tienen como alcance solo una expresión:</p> + +<pre class="brush: js notranslate">var a = 5; +let(a = 6) console.log(a); // 6 +console.log(a); // 5</pre> + +<h4 id="Reglas_de_alcance_3">Reglas de alcance</h4> + +<p>Dada la expresión <code>let</code> siguiente:</p> + +<pre class="eval notranslate">let (<var>decls</var>) <var>expr</var> +</pre> + +<p>Existe un bloque implícito creado alrededor de expr.</p> + +<h2 id="Especificaciones">Especificaciones</h2> + +<table class="standard-table"> + <tbody> + <tr> + <th scope="col">Especificación</th> + <th scope="col">Estado</th> + <th scope="col">Comentarios</th> + </tr> + <tr> + <td>{{SpecName('ES2015', '#sec-let-and-const-declarations', 'Let and Const Declarations')}}</td> + <td>{{Spec2('ES2015')}}</td> + <td>Definición initial. No especifica expresiones ni declaraciones let.</td> + </tr> + </tbody> +</table> + +<h2 id="Compatibilidad_en_navegadores">Compatibilidad en navegadores</h2> + +<h2 id="CompatibilityTable"><span style="font-size: 14px; font-weight: normal; line-height: 1.5;">{{CompatibilityTable}}</span></h2> + +<div id="compat-desktop"> +<table class="compat-table"> + <tbody> + <tr> + <th>Característica</th> + <th>Chrome</th> + <th>Firefox (Gecko)</th> + <th>Internet Explorer</th> + <th>Opera</th> + <th>Safari</th> + </tr> + <tr> + <td>Soporte básico</td> + <td> + <p class="p1">{{CompatChrome(41.0)}}</p> + </td> + <td>{{ CompatGeckoDesktop("1.8.1") }} [1]</td> + <td>11</td> + <td>17</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>Zona muerta temporal</td> + <td>{{CompatUnknown}}</td> + <td>{{ CompatGeckoDesktop("35") }} [1]</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>Expresión<code> let</code> {{non-standard_inline}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoDesktop("1.8.1") }}-{{ CompatGeckoDesktop("40") }} [1]</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Bloque<code> let</code> {{non-standard_inline}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoDesktop("1.8.1") }} [1]</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<div id="compat-mobile"> +<table class="compat-table"> + <tbody> + <tr> + <th>Característica</th> + <th>Android</th> + <th>Chrome para Android</th> + <th>Firefox Mobile (Gecko)</th> + <th>IE Mobile</th> + <th>Opera Mobile</th> + <th>Safari Mobile</th> + </tr> + <tr> + <td>Soporte básico</td> + <td>{{CompatUnknown}}</td> + <td> + <p class="p1">{{CompatChrome(41.0)}}</p> + </td> + <td>{{ CompatGeckoMobile("1.8.1") }} [1]</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>Zona muerta temporal</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{ CompatGeckoMobile("35") }} [1]</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + <td>{{CompatUnknown}}</td> + </tr> + <tr> + <td>Expresión<code> let</code> {{non-standard_inline}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoMobile("1.8.1") }}-{{ CompatGeckoMobile("40") }}[1]</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + <tr> + <td>Bloque<code> let</code> {{non-standard_inline}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{ CompatGeckoMobile("1.8.1") }} [1]</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + <td>{{CompatNo}}</td> + </tr> + </tbody> +</table> +</div> + +<h3 id="Notas_específicas_a_Firefox">Notas específicas a Firefox</h3> + +<ul> + <li>[1]: Solo disponible para bloques de codigo HTML dentro de una etiqueta <code><script> type="application/javascript;version=1.7"></code> (o de una versión mayor). Es necesario tomar en cuenta que esta es una característica no estándar, esto puede crear conflictos con otros navegadores. Las etiquetas <a href="https://developer.mozilla.org/en-US/docs/XUL">XUL</a> tienen acceso a esas características sin necesidad de dicho bloque. Ver<span style="line-height: 1.5;">{{bug(932513)}}.</span></li> + <li>Conformidad con ES2015 para <code>let</code> en SpIderMonkey es monitoreado en {{bug(950547)}} y extensiones no-standar seran eliminadas en el futuro {{bug(1023609)}}.</li> +</ul> + +<h2 id="Ver_también">Ver también</h2> + +<ul> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/var"><code>var</code></a></li> + <li><a href="/en-US/docs/Web/JavaScript/Reference/Statements/const"><code>const</code></a></li> +</ul> |