javascript - ecmascript - node js let var




Qual è la differenza tra l'uso di "let" e "var" per dichiarare una variabile in JavaScript? (18)

let

Ambito di blocco

Le variabili dichiarate usando la parola chiave let sono a scope, il che significa che sono disponibili solo nel blocco in cui sono state dichiarate.

Al livello superiore (al di fuori di una funzione)

Al livello più alto, le variabili dichiarate usando let non creano proprietà sull'oggetto globale.

var globalVariable = 42;
let blockScopedVariable = 43;

console.log(globalVariable); // 42
console.log(blockScopedVariable); // 43

console.log(this.globalVariable); // 42
console.log(this.blockScopedVariable); // undefined

All'interno di una funzione

All'interno di una funzione (ma al di fuori di un blocco), let ha lo stesso scope di 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

All'interno di un blocco

Non è possibile accedere alle variabili dichiarate usando let all'interno di un blocco al di fuori di quel blocco.

{
  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

All'interno di un ciclo

Le variabili dichiarate con anelli di penetrazione possono essere referenziate solo all'interno di quel ciclo.

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.

Loop con chiusure

Se si usa let invece di var in un ciclo, con ogni iterazione si ottiene una nuova variabile. Ciò significa che puoi tranquillamente usare una chiusura all'interno di un loop.

// 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 morta temporale

A causa della zona morta temporale , le variabili dichiarate usando let non possono essere lette prima di essere dichiarate. Il tentativo di farlo genera un errore.

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

No re-declaring

Non è possibile dichiarare la stessa variabile più volte utilizzando let . Non è inoltre possibile dichiarare una variabile usando let con lo stesso identificatore di un'altra variabile che è stata dichiarata 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 è abbastanza simile a let -it ha un ambito di blocco e ha TDZ. Vi sono, tuttavia, due cose che sono diverse.

Nessun riassegnazione

La variabile dichiarata usando const non può essere riassegnata.

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

Si noti che non significa che il valore è immutabile. Le sue proprietà possono ancora essere modificate.

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

Se vuoi avere un oggetto immutabile, dovresti usare Object.freeze() .

Initializer è richiesto

Devi sempre specificare un valore quando dichiari una variabile usando const .

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

ECMAScript 6 ha introdotto la dichiarazione di let . L'ho sentito descritto come una variabile "locale", ma non sono ancora abbastanza sicuro di come si comporta in modo diverso rispetto alla parola chiave var .

Quali sono le differenze? Quando dovrebbe essere usato su var ?


Ambito della funzione VS Block:

La principale differenza tra vared letè che le variabili dichiarate con varsono scope scope . Mentre le funzioni dichiarate letsono a scope . Per esempio:

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 

variabili con var:

Quando testVarviene chiamata la prima funzione, la variabile foo, dichiarata con var, è ancora accessibile al di fuori ifdell'istruzione. Questa variabile foosarebbe disponibile ovunque nell'ambito della testVar funzione .

variabili con let:

Quando testLetviene richiamata la seconda funzione, la variabile bar, dichiarata con let, è accessibile solo all'interno ifdell'istruzione. Poiché le variabili dichiarate con letsono blocco di ambito (in cui un blocco è il codice tra parentesi graffe ad esempio if{}, for{}, function{}).

let le variabili non vengono issate:

Un'altra differenza tra vared letè che le variabili con dichiarato con let non vengono issate . Un esempio è il modo migliore per illustrare questo comportamento:

le variabili con let non vengono issate:

console.log(letVar);

let letVar = 10;
// referenceError, the variable doesn't get hoisted

variabili con var non ottenere issato:

console.log(varVar);

var varVar = 10;
// logs undefined, the variable gets hoisted

Global letnon si affeziona a window:

Una variabile dichiarata con letnell'ambito globale (che è un codice che non è in una funzione) non viene aggiunta come proprietà windowsull'oggetto globale . Ad esempio (questo codice è in ambito globale):

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


Quando dovrebbe letessere usato oltre var?

Utilizzare letoltre varogni volta che è possibile perché è semplicemente ambito più specifico. Ciò riduce potenziali conflitti di denominazione che possono verificarsi quando si ha a che fare con un grande numero di variabili. varpuò essere utilizzato quando si desidera che una variabile globale sia esplicitamente windowsull'oggetto (considerare sempre attentamente se ciò è realmente necessario).


Alla risposta accettata manca un punto:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined

Ci sono alcune sottili differenze - let scoping si comporti più come l'scope variabile fa più o meno qualsiasi altra lingua.

ad es. Esamina il blocco che li contiene, non esistono prima di essere dichiarati, ecc.

Tuttavia, vale la pena notare che let è solo una parte delle più recenti implementazioni di Javascript e ha vari gradi di supporto del browser .


Ecco un esempio per la differenza tra i due (supporto appena iniziato per chrome):

Come si può vedere la variabile var j ancora un valore al di fuori dell'ambito del ciclo for (Block Scope), ma la variabile let i non è definita al di fuori dell'ambito del ciclo 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);


Ecco una spiegazione della parola chiave let con alcuni esempi.

lascia che funzioni molto come var. La differenza principale è che l'ambito di una variabile var è l'intera funzione di chiusura

Questa tabella su Wikipedia mostra quali browser supportano Javascript 1.7.

Nota che solo i browser Mozilla e Chrome lo supportano. IE, Safari e potenzialmente altri no.


La differenza principale è la differenza di ambito , mentre let può essere disponibile solo all'interno dell'ambito che è stato dichiarato, come in ciclo for, ad esempio è possibile accedere a var al di fuori del loop. Dalla documentazione in MDN (esempi anche da MDN):

let consente di dichiarare variabili limitate nell'ambito del blocco, dell'istruzione o dell'espressione su cui viene utilizzato. Questo è diverso dalla parola chiave var , che definisce una variabile globalmente o localmente a un'intera funzione indipendentemente dall'ambito del blocco.

Le variabili dichiarate da let hanno come scope il blocco in cui sono definite, così come in ogni sotto-blocco contenuto. In questo modo, lascia che funzioni molto come var . La differenza principale è che l'ambito di una variabile var è l'intera funzione di chiusura:

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
}`

Al livello più alto di programmi e funzioni, let , a differenza di var , non crea una proprietà sull'oggetto globale. Per esempio:

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

Se utilizzato all'interno di un blocco, consente di limitare l'ambito della variabile a quel blocco. Notare la differenza tra var il cui ambito è all'interno della funzione in cui è dichiarato.

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

Inoltre, non dimenticare che è la funzione ECMA6, quindi non è ancora completamente supportata, quindi è sempre meglio trasferirla su ECMA5 usando Babel ecc ... per maggiori informazioni sul sito babel visita



let anche usare per evitare problemi con chiusure. Lega valore fresco piuttosto che mantenere un vecchio riferimento come mostrato negli esempi di seguito.

DEMO

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

Il codice sopra mostra un classico problema di chiusura di JavaScript. Il riferimento alla variabile i viene archiviato nella chiusura del gestore di clic, anziché il valore effettivo di i .

Ogni singolo click handler si riferirà allo stesso oggetto perché c'è un solo oggetto contatore che ne contiene 6, quindi ottieni sei per ogni clic.

La soluzione generale consiste nel racchiuderlo in una funzione anonima e passare i come argomento. Tali problemi possono anche essere evitati ora usando let invece var come mostrato nel codice qui sotto.

DEMO (testato in Chrome e Firefox 50)

'use strict';

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

var è una variabile globale (in grado di sollevare).

leted constè un ambito di blocco.

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


Appare anche che, almeno in Visual Studio 2015, TypeScript 1.5, "var" consente più dichiarazioni dello stesso nome di variabile in un blocco e "let" no.

Questo non genererà un errore di compilazione:

var x = 1;
var x = 2;

Questo sarà:

let x = 1;
let x = 2;

Come menzionato sopra:

La differenza è l'ambito. varè circoscritto al blocco funzione più vicino ed letè limitato al blocco di inclusione più vicino , che può essere più piccolo di un blocco funzione. Entrambi sono globali se all'esterno di qualsiasi blocco. Vediamo un esempio:

Esempio 1:

In entrambi i miei esempi ho una funzione myfunc. myfunccontiene una variabile myvaruguale a 10. Nel mio primo esempio, controllo se myvaruguale a 10 ( myvar==10). Se sì, dichiaro una variabile myvar(ora ho due variabili myvar) usando la varparola chiave e assegnandole un nuovo valore (20). Nella riga successiva stampo il suo valore sulla mia console. Dopo il blocco condizionale, stampo nuovamente il valore myvarsulla mia console. Se guardi l'output di myfunc, myvarha valore uguale a 20.

Esempio 2: nel mio secondo esempio invece di usare la varparola chiave nel mio blocco condizionale dichiaro myvarusando la letparola chiave. Ora quando chiamo myfuncottengo due output diversi: myvar=20e myvar=10.

Quindi la differenza è molto semplice, vale a dire la sua portata.


Questo articolo definisce chiaramente la differenza tra var, let e const

const è un segnale che l'identificatore non verrà riassegnato.

let, è un segnale che la variabile può essere riassegnata, ad esempio un contatore in un ciclo o uno scambio di valori in un algoritmo. Segnala anche che la variabile verrà utilizzata solo nel blocco in cui è definita, che non è sempre l'intera funzione di contenimento.

varè ora il segnale più debole disponibile quando si definisce una variabile in JavaScript. La variabile può o non può essere riassegnata e la variabile può o non può essere utilizzata per un'intera funzione, o solo per lo scopo di un blocco o di un ciclo.

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


è parte di ES6. Queste funzioni spiegheranno la differenza in modo semplice.

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
}

Controlla questo link in MDN

let x = 1;

if (x === 1) {
let x = 2;

console.log(x);
// expected output: 2
}

console.log(x);
// expected output: 1


Ora penso che ci sia una migliore definizione delle variabili per un blocco di istruzioni usando 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
}

Penso che le persone inizieranno ad usare let qui dopo in modo che abbiano scope simili in JavaScript come altri linguaggi, Java, C #, ecc.

Le persone che non hanno una chiara comprensione dell'ambito del JavaScript sono state usate per fare l'errore prima.

Il sollevamento non è supportato utilizzando let.

Con questo approccio vengono rimossi gli errori presenti in JavaScript.

Fare riferimento a ES6 approfondimenti: lascia e const per capirlo meglio.


Se leggo le specifiche in quel momento, per let fortuna può anche essere sfruttato per evitare le auto-invocazioni delle funzioni usate per simulare i soli membri privati ​​- un modello di progettazione popolare che diminuisce la leggibilità del codice, complica il debugging, che non aggiunge protezione del codice reale o altro beneficio - tranne forse la soddisfazione di qualcuno desiderio di semantica, quindi smetti di usarlo. / rant

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

Vedi ' Emulazione di interfacce private '







let