w3schools usar sirve que para entre diferencia cuando cual javascript scope ecmascript-6 var let

sirve - ¿Cuál es la diferencia entre usar "let" y "var" para declarar una variable en JavaScript?



para que sirve let javascript (27)

ECMAScript 6 introdujo la declaración let . He oído que se describe como una variable "local", pero aún no estoy seguro de cómo se comporta de manera diferente a la palabra clave var .

¿Cuáles son las diferencias? ¿Cuándo debe let usar sobre var ?


let

Alcance del bloque

Las variables declaradas con la palabra clave let tienen un ámbito de bloque, lo que significa que están disponibles solo en el bloque en el que se declararon.

En el nivel superior (fuera de una función)

En el nivel superior, las variables declaradas utilizando no let crear propiedades en el objeto global.

var globalVariable = 42; let blockScopedVariable = 43; console.log(globalVariable); // 42 console.log(blockScopedVariable); // 43 console.log(this.globalVariable); // 42 console.log(this.blockScopedVariable); // undefined

Dentro de una funcion

Dentro de una función (pero fuera de un bloque), tenga el mismo alcance que var .

(() => { var functionScopedVariable = 42; let blockScopedVariable = 43; console.log(functionScopedVariable); // 42 console.log(blockScopedVariable); // 43 })(); console.log(functionScopedVariable); // ReferenceError: functionScopedVariable is not defined console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined

Dentro de un bloque

Las variables declaradas usando let dentro de un bloque no se pueden acceder fuera de ese bloque.

{ var globalVariable = 42; let blockScopedVariable = 43; console.log(globalVariable); // 42 console.log(blockScopedVariable); // 43 } console.log(globalVariable); // 42 console.log(blockScopedVariable); // ReferenceError: blockScopedVariable is not defined

Dentro de un bucle

Las variables declaradas con bucles de entrada pueden ser referenciadas solo dentro de ese bucle.

for (var i = 0; i < 3; i++) { var j = i * 2; } console.log(i); // 3 console.log(j); // 4 for (let k = 0; k < 3; k++) { let l = k * 2; } console.log(typeof k); // undefined console.log(typeof l); // undefined // Trying to do console.log(k) or console.log(l) here would throw a ReferenceError.

Bucles con cierres

Si utiliza let lugar de var en un bucle, con cada iteración obtendrá una nueva variable. Eso significa que puede usar un cierre de forma segura dentro de un bucle.

// Logs 3 thrice, not what we meant. for (var i = 0; i < 3; i++) { setTimeout(() => console.log(i), 0); } // Logs 0, 1 and 2, as expected. for (let j = 0; j < 3; j++) { setTimeout(() => console.log(j), 0); }

Zona muerta temporal

Debido a la zona muerta temporal , no se puede acceder a las variables declaradas utilizando let antes de declararlas. Intentar hacerlo arroja un error.

console.log(noTDZ); // undefined var noTDZ = 43; console.log(hasTDZ); // ReferenceError: hasTDZ is not defined let hasTDZ = 42;

No re-declarar

No puedes declarar la misma variable varias veces usando let . Tampoco puede declarar una variable usando let con el mismo identificador que otra variable que fue declarada usando var .

var a; var a; // Works fine. let b; let b; // SyntaxError: Identifier ''b'' has already been declared var c; let c; // SyntaxError: Identifier ''c'' has already been declared

const

const es bastante similar a let que let de ámbito de bloques y tiene TDZ. Hay, sin embargo, dos cosas que son diferentes.

Sin reasignación

La variable declarada usando const no puede ser reasignada.

const a = 42; a = 43; // TypeError: Assignment to constant variable.

Tenga en cuenta que no significa que el valor sea inmutable. Sus propiedades todavía se pueden cambiar.

const obj = {}; obj.a = 42; console.log(obj.a); // 42

Si desea tener un objeto inmutable, debe usar Object.freeze() .

Se requiere inicializador

Siempre debe especificar un valor al declarar una variable usando const .

const a; // SyntaxError: Missing initializer in const declaration


Función VS ámbito de bloque:

La principal diferencia entre vary letes que las variables declaradas varson función de ámbito . Mientras que las funciones declaradas letson de ámbito de bloque . Por ejemplo:

function testVar () { if(true) { var foo = ''foo''; } console.log(foo); } testVar(); // logs ''foo'' function testLet () { if(true) { let bar = ''bar''; } console.log(bar); } testLet(); // reference error // bar is scoped to the block of the if statement

variables con var:

Cuando testVarse llama a la primera función, la variable foo, declarada con var, sigue siendo accesible fuera de la ifdeclaración. Esta variable fooestaría disponible en cualquier parte dentro del alcance de la testVar función .

variables con let:

Cuando testLetse llama a la segunda función, la barra de variables, declarada con let, solo es accesible dentro de la ifdeclaración. Debido a que las variables declaradas con letson de ámbito bloque (donde un bloque es el código entre corchetes, por ejemplo if{}, for{}, function{}).

let las variables no se echan

Otra diferencia entre vary letcon las variables declaradas con let no conseguir elevadas . Un ejemplo es la mejor manera de ilustrar este comportamiento:

Las variables con let no se echan:

console.log(letVar); let letVar = 10; // referenceError, the variable doesn''t get hoisted

variables con var hacer subir:

console.log(varVar); var varVar = 10; // logs undefined, the variable gets hoisted

Global letno se apega a window:

Una variable declarada con leten el ámbito global (que es un código que no está en una función) no se agrega como una propiedad en el windowobjeto global . Por ejemplo (este código está en alcance global):

var bar = 5; let foo = 10; console.log(bar); // logs 5 console.log(foo); // logs 10 console.log(window.bar); // logs 5, variable added to window object console.log(window.foo); // logs undefined, variable not added to window object


¿Cuándo debería letser usado más var?

Utilizar letmás varcada vez que pueda, ya que es simplemente cuyo ámbito más específico. Esto reduce los posibles conflictos de nombres que pueden ocurrir al tratar con un gran número de variables. varse puede usar cuando desea que una variable global esté explícitamente en el windowobjeto (siempre considere cuidadosamente si esto es realmente necesario)


¿Cuál es la diferencia entre let y var ?

  • Una variable definida mediante una instrucción var se conoce a través de la función en la que está definida, desde el inicio de la función. (*)
  • Una variable definida utilizando una instrucción let solo se conoce en el bloque en el que se define, desde el momento en que se define en adelante. (**)

Para entender la diferencia, considera el siguiente código:

// i IS NOT known here // j IS NOT known here // k IS known here, but undefined // l IS NOT known here function loop(arr) { // i IS known here, but undefined // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( var i = 0; i < arr.length; i++ ) { // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here for( let j = 0; j < arr.length; j++ ) { // i IS known here, and has a value // j IS known here, and has a value // k IS known here, but has a value only the second time loop is called // l IS NOT known here }; // i IS known here, and has a value // j IS NOT known here // k IS known here, but has a value only the second time loop is called // l IS NOT known here } loop([1,2,3,4]); for( var k = 0; k < arr.length; k++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here }; for( let l = 0; l < arr.length; l++ ) { // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS known here, and has a value }; loop([1,2,3,4]); // i IS NOT known here // j IS NOT known here // k IS known here, and has a value // l IS NOT known here

Aquí, podemos ver que nuestra variable j solo se conoce en el primer bucle for, pero no antes y después. Sin embargo, nuestra variable i es conocida en toda la función.

Además, tenga en cuenta que las variables de ámbito de bloque no se conocen antes de declararse porque no están elevadas. Tampoco está permitido volver a declarar la misma variable de ámbito de bloque dentro del mismo bloque. Esto hace que las variables de ámbito de bloque sean menos propensas a errores que las variables de alcance global o funcional, que se elevan y no producen errores en el caso de declaraciones múltiples.

¿Es seguro usarlo hoy?

Algunas personas argumentarán que en el futuro SOLAMENTE usaremos declaraciones de dejar y que las declaraciones de var serán obsoletas. El gurú de JavaScript, Kyle Simpson, escribió un artículo muy detallado sobre por qué no es así .

Hoy, sin embargo, ese definitivamente no es el caso. De hecho, necesitamos preguntarnos si es seguro usar la declaración let . La respuesta a esa pregunta depende de su entorno:

  • Si está escribiendo el código de JavaScript del lado del servidor ( Node.js ), puede usar la instrucción let forma segura.

  • Si está escribiendo un código de JavaScript del lado del cliente y usa un transpiler (como Traceur ), puede usar de manera segura la declaración let , sin embargo, es probable que su código sea todo menos óptimo con respecto al rendimiento.

  • Si está escribiendo el código JavaScript del lado del cliente y no utiliza un transpiler, debe considerar la compatibilidad con el navegador.

Hoy, 8 de junio de 2018, todavía hay algunos navegadores que no admiten let !

Cómo realizar un seguimiento de la compatibilidad del navegador

Para obtener una descripción actualizada de qué navegadores son compatibles con la declaración de let en el momento de leer esta respuesta, consulte esta página Can I Use ?

(*) Las variables de alcance global y funcional pueden inicializarse y usarse antes de declararse porque las variables de JavaScript están hoisted . Esto significa que las declaraciones están siempre en la parte superior del alcance.

(**) Las variables de ámbito de bloque no son elevadas.


A la respuesta aceptada le falta un punto:

{ let a = 123; }; console.log(a); // ReferenceError: a is not defined


Aquí hay un ejemplo de la diferencia entre los dos (el soporte acaba de comenzar para Chrome):

Como puede ver, la variable var j sigue teniendo un valor fuera del alcance del bucle for (Ámbito del bloque), pero la variable let i no está definida fuera del alcance del bucle for.

"use strict"; console.log("var:"); for (var j = 0; j < 2; j++) { console.log(j); } console.log(j); console.log("let:"); for (let i = 0; i < 2; i++) { console.log(i); } console.log(i);


Aquí hay un ejemplo para agregar a lo que otros ya han escrito. Supongamos que desea crear una matriz de funciones, funciones adderFunctions , donde cada función toma un solo argumento de Número y devuelve la suma del argumento y el índice de la función en la matriz. Tratar de generar adderFunctions con un bucle usando la palabra clave var no funcionará de la manera que alguien podría esperar ingenuamente:

// An array of adder functions. var adderFunctions = []; for (var i = 0; i < 1000; i++) { // We want the function at index i to add the index to its argument. adderFunctions[i] = function(x) { // What is i bound to here? return x + i; }; } var add12 = adderFunctions[12]; // Uh oh. The function is bound to i in the outer scope, which is currently 1000. console.log(add12(8) === 20); // => false console.log(add12(8) === 1008); // => true console.log(i); // => 1000 // It gets worse. i = -8; console.log(add12(8) === 0); // => true

El proceso anterior no genera la matriz de funciones deseada porque el alcance de i extiende más allá de la iteración del bloque for en el que se creó cada función. En cambio, al final del bucle, la i en el cierre de cada función se refiere al valor de i al final del bucle (1000) para cada función anónima en adderFunctions . Esto no es lo que queríamos en absoluto: ahora tenemos una matriz de 1000 funciones diferentes en la memoria con exactamente el mismo comportamiento. Y si posteriormente actualizamos el valor de i , la mutación afectará a todas las adderFunctions .

Sin embargo, podemos volver a intentarlo utilizando la palabra clave let :

// Let''s try this again. // NOTE: We''re using another ES6 keyword, const, for values that won''t // be reassigned. const and let have similar scoping behavior. const adderFunctions = []; for (let i = 0; i < 1000; i++) { // NOTE: We''re using the newer arrow function syntax this time, but // using the "function(x) { ..." syntax from the previous example // here would not change the behavior shown. adderFunctions[i] = x => x + i; } const add12 = adderFunctions[12]; // Yay! The behavior is as expected. console.log(add12(8) === 20); // => true // i''s scope doesn''t extend outside the for loop. console.log(i); // => ReferenceError: i is not defined

Esta vez, i es rebote en cada iteración del bucle for . Cada función ahora mantiene el valor de i en el momento de la creación de la función, y las funciones de adderFunctions comportan como se espera.

Ahora, la imagen mezcla los dos comportamientos y probablemente verá por qué no se recomienda mezclar las nuevas let y const con las var más antiguas en el mismo script. Hacerlo puede resultar en un código espectacularmente confuso.

const doubleAdderFunctions = []; for (var i = 0; i < 1000; i++) { const j = i; doubleAdderFunctions[i] = x => x + i + j; } const add18 = doubleAdderFunctions[9]; const add24 = doubleAdderFunctions[12]; // It''s not fun debugging situations like this, especially when the // code is more complex than in this example. console.log(add18(24) === 42); // => false console.log(add24(18) === 42); // => false console.log(add18(24) === add24(18)); // => false console.log(add18(24) === 2018); // => false console.log(add24(18) === 2018); // => false console.log(add18(24) === 1033); // => true console.log(add24(18) === 1030); // => true

No dejes que esto te pase a ti. Usa una plantilla.

NOTA: Este es un ejemplo de enseñanza destinado a demostrar el comportamiento var / let en bucles y con cierres de funciones que también serían fáciles de entender. Esta sería una manera terrible de sumar números. Pero la técnica general de captura de datos en cierres de funciones anónimas puede encontrarse en el mundo real en otros contextos. YMMV.


Aquí hay una explicación de la palabra clave let con algunos ejemplos.

Dejamos los trabajos muy parecidos a var. La principal diferencia es que el alcance de una variable var es la función de cierre completa.

Esta tabla en Wikipedia muestra qué navegadores son compatibles con Javascript 1.7.

Tenga en cuenta que solo los navegadores Mozilla y Chrome lo admiten. IE, Safari, y potencialmente otros no.


Hay algunas diferencias sutiles: let alcance se comporte más como el alcance variable en más o menos otros idiomas.

Por ejemplo, se dirige al bloque adjunto, no existen antes de que se declaren, etc.

Sin embargo, vale la pena señalar que let solo una parte de las nuevas implementaciones de Javascript y que tiene diversos grados de compatibilidad con el navegador .


La diferencia es el alcance. var encuentra dentro del alcance del bloque de función más cercano y se le asigna el alcance al bloque de cierre más cercano, que puede ser más pequeño que un bloque de función. Ambos son globales si están fuera de cualquier bloque.

Además, las variables declaradas con let no son accesibles antes de que se declaren en su bloque adjunto. Como se ve en la demostración, esto lanzará una excepción ReferenceError.

Demo :

var html = ''''; write(''#### global ####/n''); write(''globalVar: '' + globalVar); //undefined, but visible try { write(''globalLet: '' + globalLet); //undefined, *not* visible } catch (exception) { write(''globalLet: exception''); } write(''/nset variables''); var globalVar = ''globalVar''; let globalLet = ''globalLet''; write(''/nglobalVar: '' + globalVar); write(''globalLet: '' + globalLet); function functionScoped() { write(''/n#### function ####''); write(''/nfunctionVar: '' + functionVar); //undefined, but visible try { write(''functionLet: '' + functionLet); //undefined, *not* visible } catch (exception) { write(''functionLet: exception''); } write(''/nset variables''); var functionVar = ''functionVar''; let functionLet = ''functionLet''; write(''/nfunctionVar: '' + functionVar); write(''functionLet: '' + functionLet); } function blockScoped() { write(''/n#### block ####''); write(''/nblockVar: '' + blockVar); //undefined, but visible try { write(''blockLet: '' + blockLet); //undefined, *not* visible } catch (exception) { write(''blockLet: exception''); } for (var blockVar = ''blockVar'', blockIndex = 0; blockIndex < 1; blockIndex++) { write(''/nblockVar: '' + blockVar); // visible here and whole function }; for (let blockLet = ''blockLet'', letIndex = 0; letIndex < 1; letIndex++) { write(''blockLet: '' + blockLet); // visible only here }; write(''/nblockVar: '' + blockVar); try { write(''blockLet: '' + blockLet); //undefined, *not* visible } catch (exception) { write(''blockLet: exception''); } } function write(line) { html += (line ? line : '''') + ''<br />''; } functionScoped(); blockScoped(); document.getElementById(''results'').innerHTML = html;

<pre id="results"></pre>

Global:

Son muy similares cuando se usan así fuera de un bloque de función.

let me = ''go''; // globally scoped var i = ''able''; // globally scoped

Sin embargo, las variables globales definidas con let no se agregarán como propiedades en el objeto de window global como las definidas con var .

console.log(window.me); // undefined console.log(window.i); // ''able''

Función:

Son idénticos cuando se usan así en un bloque de función.

function ingWithinEstablishedParameters() { let terOfRecommendation = ''awesome worker!''; //function block scoped var sityCheerleading = ''go!''; //function block scoped }

Bloquear:

Aquí está la diferencia. let solo es visible en el bucle for() y var es visible para toda la función.

function allyIlliterate() { //tuce is *not* visible out here for( let tuce = 0; tuce < 5; tuce++ ) { //tuce is only visible in here (and in the for() parentheses) //and there is a separate tuce variable for each iteration of the loop } //tuce is *not* visible out here } function byE40() { //nish *is* visible out here for( var nish = 0; nish < 5; nish++ ) { //nish is visible to the whole function } //nish *is* visible out here }

Redeclaración:

Suponiendo un modo estricto, var le permitirá volver a declarar la misma variable en el mismo ámbito. Por otro lado, let haremos:

''use strict''; let me = ''foo''; let me = ''bar''; // SyntaxError: Identifier ''me'' has already been declared

''use strict''; var me = ''foo''; var me = ''bar''; // No problem, `me` is replaced.


La principal diferencia es la diferencia de alcance , mientras que let solo puede estar disponible dentro del alcance que está declarado, como en for loop, por ejemplo, se puede acceder a var fuera del loop. De la documentación en MDN (ejemplos también de MDN):

let le permite declarar variables que están limitadas en su alcance al bloque, la declaración o la expresión en la que se utiliza. Esto es diferente a la palabra clave var , que define una variable globalmente, o localmente a una función completa, independientemente del alcance del bloque.

Las variables declaradas por let tienen como su alcance el bloque en el que están definidas, así como en cualquier sub-bloque contenido. De esta manera, dejemos que los trabajos se parezcan mucho a la var . La principal diferencia es que el alcance de una variable var es la función de cierre completa:

function varTest() { var x = 1; if (true) { var x = 2; // same variable! console.log(x); // 2 } console.log(x); // 2 } function letTest() { let x = 1; if (true) { let x = 2; // different variable console.log(x); // 2 } console.log(x); // 1 }`

En el nivel superior de programas y funciones, a diferencia de var , no crea una propiedad en el objeto global. Por ejemplo:

var x = ''global''; let y = ''global''; console.log(this.x); // "global" console.log(this.y); // undefined

Cuando se utiliza dentro de un bloque, permite limitar el alcance de la variable a ese bloque. Note la diferencia entre var cuyo alcance está dentro de la función donde se declara.

var a = 1; var b = 2; if (a === 1) { var a = 11; // the scope is global let b = 22; // the scope is inside the if-block console.log(a); // 11 console.log(b); // 22 } console.log(a); // 11 console.log(b); // 2

Además, no olvide que es la función ECMA6, por lo que aún no está totalmente soportada, así que es mejor que siempre la transfiera a ECMA5 utilizando Babel, etc. Para obtener más información sobre el sitio web babel visite



let Es interesante, porque nos permite hacer algo como esto:

(() => { var count = 0; for (let i = 0; i < 2; ++i) { for (let i = 0; i < 2; ++i) { for (let i = 0; i < 2; ++i) { console.log(count++); } } } })();

Lo que resulta en el conteo [0, 7].

Mientras

(() => { var count = 0; for (var i = 0; i < 2; ++i) { for (var i = 0; i < 2; ++i) { for (var i = 0; i < 2; ++i) { console.log(count++); } } } })();

Solo cuenta [0, 1].


let también puede ser usado para evitar problemas con los cierres. Enlaza valor nuevo en lugar de mantener una referencia antigua como se muestra en los ejemplos a continuación.

DEMO

for(var i = 1; i < 6; i++) { document.getElementById(''my-element'' + i) .addEventListener(''click'', function() { alert(i) }) }

El código anterior demuestra un problema clásico de cierre de JavaScript. La referencia a la variable i se almacena en el cierre del controlador de clic, en lugar del valor real de i .

Cada controlador de un solo clic se referirá al mismo objeto porque solo hay un objeto de contador que contiene 6, por lo que obtiene seis en cada clic.

La solución general es envolver esto en una función anónima y pasar i como argumento. Tales problemas también se pueden evitar ahora utilizando let lugar de var como se muestra en el código a continuación.

DEMO (Probado en Chrome y Firefox 50)

''use strict''; for(let i = 1; i < 6; i++) { document.getElementById(''my-element'' + i) .addEventListener(''click'', function() { alert(i) }) }


var Es una variable de alcance global (elevable).

lety constes ámbito de bloque.

test.js

{ let l = ''let''; const c = ''const''; var v = ''var''; v2 = ''var 2''; } console.log(v, this.v); console.log(v2, this.v2); console.log(l); // ReferenceError: l is not defined console.log(c); // ReferenceError: c is not defined


Cuando usas let

La letpalabra clave adjunta la declaración de variable al alcance de cualquier bloque (generalmente un { .. }par) en el que se encuentra. En otras palabras, letsecuestra de forma implícita el alcance de cualquier bloque para su declaración de variable.

letno se puede acceder a las variables en el windowobjeto porque no se puede acceder a ellas globalmente.

function a(){ { // this is the Max Scope for let variable let x = 12; } console.log(x); } a(); // Uncaught ReferenceError: x is not defined

Cuando usas var

var y las variables en ES5 tienen ámbitos en las funciones, lo que significa que las variables son válidas dentro de la función y no fuera de la función en sí.

varSe puede acceder a las variables en el windowobjeto porque no se puede acceder a ellas globalmente.

function a(){ // this is the Max Scope for var variable { var x = 12; } console.log(x); } a(); // 12

Si quieres saber más sigue leyendo a continuación.

una de las preguntas de entrevista más famosas sobre el alcance también puede ser suficiente con el uso exacto de lety varcomo se muestra a continuación;

Cuando usas let

for (let i = 0; i < 10 ; i++) { setTimeout( function a() { console.log(i); //print 0 to 9, that is literally AWW!!! }, 100 * i); }

Esto se debe a que, al usar let, para cada iteración de bucle, la variable tiene un ámbito y tiene su propia copia.

Cuando usas var

for (var i = 0; i < 10 ; i++) { setTimeout( function a() { console.log(i); //print 10 times 10 }, 100 * i); }

Esto se debe a que, al usar var, para cada iteración de bucle, la variable tiene un ámbito y tiene una copia compartida.


Como se ha mencionado más arriba:

La diferencia es el alcance. vartiene el alcance del bloque de función más cercano y el letalcance del bloque de cierre más cercano , que puede ser más pequeño que un bloque de función. Ambos son globales si están fuera de cualquier bloque. Veamos un ejemplo:

Ejemplo 1:

En mis dos ejemplos tengo una función myfunc. myfunccontiene una variable myvarigual a 10. En mi primer ejemplo, compruebo si myvares igual a 10 ( myvar==10). En caso afirmativo, nuevamente declaro una variable myvar(ahora tengo dos variables myvar) usando varpalabras clave y le asigno un nuevo valor (20) En la siguiente línea imprimo su valor en mi consola. Después del bloque condicional, de nuevo imprimo el valor de myvaren mi consola. Si nos fijamos en la salida de myfunc, myvartiene valor igual a 20.

Ejemplo 2: en mi segundo ejemplo, en lugar de usar varpalabras clave en mi bloque condicional, declaro myvarusar letpalabras clave. Ahora cuando llamo myfuncme sale dos salidas diferentes: myvar=20y myvar=10.

Así que la diferencia es muy simple, es decir, su alcance.


Este artículo define claramente la diferencia entre var, let y const.

const es una señal de que el identificador no será reasignado.

let, es una señal de que la variable puede ser reasignada, como un contador en un bucle o un intercambio de valores en un algoritmo. También indica que la variable se usará solo en el bloque en el que se define, lo que no siempre es la función que contiene todo.

varAhora es la señal más débil disponible cuando define una variable en JavaScript. La variable puede o no ser reasignada, y la variable puede o no ser utilizada para una función completa, o solo para el propósito de un bloque o bucle.

https://medium.com/javascript-scene/javascript-es6-var-let-or-const-ba58b8dcde75#.esmkpbg9b


Que las dos funciones siguientes muestren la diferencia:

function varTest() { var x = 31; if (true) { var x = 71; // Same variable! console.log(x); // 71 } console.log(x); // 71 } function letTest() { let x = 31; if (true) { let x = 71; // Different variable console.log(x); // 71 } console.log(x); // 31 }


También parece que, al menos en Visual Studio 2015, TypeScript 1.5, "var" permite múltiples declaraciones del mismo nombre de variable en un bloque, y "let" no.

Esto no generará un error de compilación:

var x = 1; var x = 2;

Esta voluntad:

let x = 1; let x = 2;


Ahora creo que hay un mejor alcance de las variables a un bloque de declaraciones utilizando let:

function printnums() { // i is not accessible here for(let i = 0; i <10; i+=) { console.log(i); } // i is not accessible here // j is accessible here for(var j = 0; j <10; j++) { console.log(j); } // j is accessible here }

Creo que la gente comenzará a usar Let here after para que tengan un alcance similar en JavaScript como otros lenguajes, Java, C #, etc.

Las personas que no tienen una comprensión clara sobre el alcance en JavaScript solían cometer el error antes.

No se soporta el izamiento utilizando let.

Con este enfoque se eliminan los errores presentes en JavaScript.

Refiérase a ES6 en profundidad: deje que consten para entenderlo mejor.


Algunos hacks con let:

1.

let statistics = [16, 170, 10]; let [age, height, grade] = statistics; console.log(height)

2.

let x = 120, y = 12; [x, y] = [y, x]; console.log(`x: ${x} y: ${y}`);

3.

let node = { type: "Identifier", name: "foo" }; let { type, name, value } = node; console.log(type); // "Identifier" console.log(name); // "foo" console.log(value); // undefined let node = { type: "Identifier" }; let { type: localType, name: localName = "bar" } = node; console.log(localType); // "Identifier" console.log(localName); // "bar"

Getter y setter con let:

let jar = { numberOfCookies: 10, get cookies() { return this.numberOfCookies; }, set cookies(value) { this.numberOfCookies = value; } }; console.log(jar.cookies) jar.cookies = 7; console.log(jar.cookies)



La diferencia está en el scope de las variables declaradas con cada una.

En la práctica, hay una serie de consecuencias útiles de la diferencia en el alcance:

  1. letlas variables solo son visibles en su bloque de cierre más cercano ( { ... }).
  2. letlas variables solo se pueden usar en líneas de código que se producen después de que se declara la variable (¡aunque se hayan izado !)
  3. letLas variables no pueden ser redeclaradas por un posterior varo let.
  4. Las letvariables globales no se agregan al windowobjeto global .
  5. letLas variables son fáciles de usar con cierres (no causan condiciones de carrera ).

Las restricciones impuestas letreducen la visibilidad de las variables y aumentan la probabilidad de que las colisiones de nombres inesperadas se encuentren pronto. Esto facilita el seguimiento y el razonamiento de las variables, incluida su reachability (lo que ayuda a recuperar la memoria no utilizada).

En consecuencia, letes menos probable que las variables causen problemas cuando se usan en programas grandes o cuando los marcos desarrollados de forma independiente se combinan de formas nuevas e inesperadas.

varaún puede ser útil si está seguro de que desea el efecto de enlace único cuando utiliza un cierre en un bucle (# 5) o para declarar variables globales visibles externamente en su código (# 4). El uso de varfor export puede ser suplantado si exportmigra fuera del espacio del transpiler al idioma central.

Ejemplos

1. Sin uso fuera del bloque de cierre más cercano: este bloque de código generará un error de referencia porque el segundo uso se xproduce fuera del bloque donde se declara con let:

{ let x = 1; } console.log(`x is ${x}`); // ReferenceError during parsing: "x is not defined".

En contraste, el mismo ejemplo con varobras.

2. Sin uso antes de la declaración:
este bloque de código lanzará un ReferenceErrorcódigo antes de que se pueda ejecutar el código porque xse usa antes de declararlo

{ x = x + 1; // ReferenceError during parsing: "x is not defined". let x; console.log(`x is ${x}`); // Never runs. }

Por el contrario, el mismo ejemplo varanaliza y ejecuta sin lanzar excepciones.

3. No redeclaración: el siguiente código demuestra que una variable declarada con letno se puede volver a declarar más adelante:

let x = 1; let x = 2; // SyntaxError: Identifier ''x'' has already been declared

4. Globales no adheridos a window:

var button = "I cause accidents because my name is too common."; let link = "Though my name is common, I am harder to access from other JS files."; console.log(link); // OK console.log(window.link); // undefined (GOOD!) console.log(window.button); // OK

5. Fácil uso con cierres: las variables declaradas varno funcionan bien con cierres dentro de los bucles. Aquí hay un bucle simple que genera la secuencia de valores que la variable itiene en diferentes puntos en el tiempo:

for (let i = 0; i < 5; i++) { console.log(`i is ${i}`), 125/*ms*/); }

Específicamente, esto produce:

i is 0 i is 1 i is 2 i is 3 i is 4

En JavaScript, a menudo utilizamos variables mucho más tarde que cuando se crean. Cuando demostramos esto retrasando la salida con un cierre pasado a setTimeout:

for (let i = 0; i < 5; i++) { setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/); }

... la salida permanece sin cambios mientras nos mantengamos let. Por el contrario, si hubiéramos utilizado en su var ilugar:

for (var i = 0; i < 5; i++) { setTimeout(_ => console.log(`i is ${i}`), 125/*ms*/); }

... el bucle genera inesperadamente "i is 5" cinco veces:

i is 5 i is 5 i is 5 i is 5 i is 5


Let es una parte de es6. Estas funciones explicarán la diferencia de manera fácil.

function varTest() { var x = 1; if (true) { var x = 2; // same variable! console.log(x); // 2 } console.log(x); // 2 } function letTest() { let x = 1; if (true) { let x = 2; // different variable console.log(x); // 2 } console.log(x); // 1 }


Revisa este enlace en MDN

let x = 1; if (x === 1) { let x = 2; console.log(x); // expected output: 2 } console.log(x); // expected output: 1


Si leo las especificaciones correctamente, let afortunadamente también se puede aprovechar para evitar las funciones de auto-invocación usadas para simular miembros exclusivos privados, un patrón de diseño popular que reduce la legibilidad del código, complica la depuración, que no agrega protección de código real ni otro beneficio Deseo de semántica, así que deja de usarlo. /despotricar

var SomeConstructor; { let privateScope = {}; SomeConstructor = function SomeConstructor () { this.someProperty = "foo"; privateScope.hiddenProperty = "bar"; } SomeConstructor.prototype.showPublic = function () { console.log(this.someProperty); // foo } SomeConstructor.prototype.showPrivate = function () { console.log(privateScope.hiddenProperty); // bar } } var myInstance = new SomeConstructor(); myInstance.showPublic(); myInstance.showPrivate(); console.log(privateScope.hiddenProperty); // error

Consulte '' Emulación de interfaces privadas ''.


  • Variable No Levantamiento

    no levantemos todo el alcance del bloque en el que aparecen. Por el contrario, var podría levantar como se muestra a continuación.

    { console.log(cc); // undefined. Caused by hoisting var cc = 23; } { console.log(bb); // ReferenceError: bb is not defined let bb = 23; }

    En realidad, Per @ Bergi, ambas var y let son izados .

  • Recolección de basura

    El ámbito de bloqueo de let es útil se relaciona con los cierres y la recolección de basura para recuperar memoria. Considerar,

    function process(data) { //... } var hugeData = { .. }; process(hugeData); var btn = document.getElementById("mybutton"); btn.addEventListener( "click", function click(evt){ //.... });

    La devolución de llamada del controlador de click no necesita la variable hugeData en absoluto. Teóricamente, después de que process(..) ejecuta el process(..) , la enorme estructura de datos hugeData podría ser recogida de basura. Sin embargo, es posible que algún motor JS aún tenga que mantener esta enorme estructura, ya que la función de click tiene un cierre en todo el alcance.

    Sin embargo, el ámbito de bloque puede hacer que esta enorme estructura de datos se recoja en la basura.

    function process(data) { //... } { // anything declared inside this block can be garbage collected let hugeData = { .. }; process(hugeData); } var btn = document.getElementById("mybutton"); btn.addEventListener( "click", function click(evt){ //.... });

  • let bucles

    let el bucle pueda volver a vincularlo a cada iteración del bucle, asegurándose de volver a asignarle el valor del final de la iteración del bucle anterior. Considerar,

    // print ''5'' 5 times for (var i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); }, 1000); }

    Sin embargo, reemplace var con let

    // print 1, 2, 3, 4, 5. now for (let i = 0; i < 5; ++i) { setTimeout(function () { console.log(i); }, 1000); }

    Debido a let creamos un nuevo entorno léxico con esos nombres para a) la expresión inicializadora b) cada iteración (antes de evaluar la expresión de incremento), here hay más detalles.