Quelle est la différence entre utiliser "let" et "var" pour déclarer une variable en JavaScript?

ECMAScript 6 introduit le let déclaration . J'ai entendu dire qu'il s'agit d'une variable" locale", mais je ne sais toujours pas comment elle se comporte différemment du mot-clé var .

Quelles sont les différences? Quand utiliser let au lieu de var ?

3388
demandé sur Cœur 2009-04-18 00:09:26
la source

27 ответов

La différence est portée. var est scopé au bloc de fonctions le plus proche et let est scopé au bloc de fonctions le plus proche entourant , qui peut être plus petit qu'un bloc de fonctions. Les deux sont globales si en dehors de n'importe quel bloc.

de plus, les variables déclarées avec let ne sont pas accessibles avant d'être déclarées dans leur bloc d'inclusion. Comme vu dans la démo, cela lancera une exception ReferenceError.

Démo :

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>

Mondial:

ils sont très similaires lorsqu'ils sont utilisés comme ceci en dehors d'un bloc de fonctions.

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

cependant, les variables globales définies avec let ne seront pas ajoutées en tant que Propriétés sur l'objet global window comme celles définies avec var .

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

fonction:

ils sont identiques lorsqu'ils sont utilisés comme ceci dans un bloc de fonctions.

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

bloc:

Voici la différence. let n'est visible que dans la boucle for() et var est visible par l'ensemble de la fonction.

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
}

Redeclaration:

en mode strict, var vous permettra de re-déclarer le même variable dans la même portée. D'autre part, let ne sera pas:

'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.
4725
répondu ThinkingStiff 2018-02-05 13:22:50
la source

let peut également être utilisé pour éviter les problèmes avec les fermetures. Il lie la valeur fraîche plutôt que de garder une vieille référence comme montré dans les exemples ci-dessous.

DÉMO

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

ci-dessus démontre un problème de fermeture JavaScript classique. La référence à la variable i est stockée dans la fermeture du gestionnaire de clic, plutôt que la valeur réelle de i .

chaque gestionnaire de clic simple se référera au même objet parce qu'il n'y a qu'un seul contre-objet qui tient 6 donc vous obtenez six sur chaque clic.

contournement général est d'envelopper cela dans une fonction anonyme et passer i comme argument. Ces problèmes peuvent également être évités en utilisant let au lieu de var comme indiqué dans le code ci-dessous.

DÉMO (Testé dans Chrome et Firefox 50)

'use strict';

for(let i = 1; i < 6; i++) {
  document.getElementById('my-element' + i)
    .addEventListener('click', function() { alert(i) })
}
459
répondu Gurpreet Singh 2017-05-08 17:04:46
la source

voici une explication du let mot-clé avec quelques exemples.

laissez fonctionne très bien comme var. La principale différence est que la portée d'une variable var est l'ensemble de la fonction englobante

ce tableau sur Wikipedia montre quels navigateurs supportent Javascript 1.7.

notez que seuls les navigateurs Mozilla et Chrome le supportent. IE, Safari, et peut-être pas d'autres.

134
répondu Ben S 2015-09-16 16:44:41
la source

Quelle est la différence entre let et var ?

  • une variable définie à l'aide d'un var est connue tout au long de la fonction elle est définie dans, dès le début de la fonction. (*)
  • une variable définie au moyen d'un énoncé let n'est connue que dans le bloc il est défini dans, à partir du moment où il est défini. (**)

pour comprendre la différence, considérez le code suivant:

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

ici, nous pouvons voir que notre variable j est seulement connu dans le premier pour boucle, mais pas avant et après. Pourtant, notre variable i est connue dans toute la fonction.

aussi, considérer que bloc variables scoped ne sont pas connus avant qu'ils ne soient déclarés parce qu'ils ne sont pas hissés. Vous n'êtes pas non plus autorisé à faire une nouvelle sélection de la même variable à l'intérieur du même bloc. Cela rend les variables à portée de bloc moins sujettes aux erreurs que les variables à portée globale ou fonctionnelle, qui sont hissées et qui ne produisent pas d'erreurs dans le cas de déclarations multiples.


est-il sûr d'utiliser let aujourd'hui?

certains diraient qu'à l'avenir, nous N'utiliserons que les déclarations let et que les déclarations var deviendront obsolètes. JavaScript gourou Kyle Simpson a écrit un article très élaboré sur les raisons pour lesquelles ce n'est pas le cas .

aujourd'Hui, cependant, ce n'est certainement pas le cas. En fait, nous devons nous demander s'il est sans danger d'utiliser la déclaration let . La réponse à cette question dépend de votre environnement:

  • si vous écrivez un code JavaScript côté serveur ( noeud.js ), vous pouvez utiliser en toute sécurité la déclaration let .

  • si vous écrivez un code JavaScript côté client et utilisez un transpirateur (comme Traceur ), vous pouvez utiliser en toute sécurité la déclaration let , cependant votre code est susceptible d'être tout sauf optimal en ce qui concerne la performance.

  • si vous écrivez du code JavaScript côté client et que vous n'utilisez pas de transpirateur, vous devez prendre en compte le support du navigateur.

Aujourd'hui, 8 juin 2018, il y a encore quelques navigateurs qui ne prennent pas en charge let !

enter image description here


Comment garder une trace de la prise en charge du navigateur

pour un aperçu à jour des navigateurs qui supportent l'énoncé let au moment de la lecture de cette réponse, voir ce Can I Use page .


(*) globalement et fonctionnellement les variables scopées peuvent être initialisées et utilisées avant d'être déclarées car JavaScript les variables sont hissé . cela signifie que les déclarations occupent toujours une place prépondérante.

(**) les variables à portée de bloc ne sont pas hissées

125
répondu John Slegers 2018-06-10 13:53:09
la source

la réponse acceptée manque un point:

{
  let a = 123;
};

console.log(a); // ReferenceError: a is not defined
100
répondu Lcf.vs 2016-07-14 17:13:44
la source

il y a quelques différences subtiles -- let l'établissement de la portée se comporte plus comme l'établissement de la portée variable le fait dans plus ou moins d'autres langues.

par exemple, Il étendues à l'affichage de bloc, Ils n'existent pas avant qu'ils ne soient déclarés, etc.

cependant, il est intéressant de noter que let est seulement une partie des nouvelles implémentations Javascript et a des degrés variables de soutien du navigateur .

40
répondu olliej 2015-10-22 16:15:35
la source

voici un exemple pour la différence entre les deux (le support vient de démarrer pour chrome): enter image description here

comme vous pouvez le voir, la variable var j a toujours une valeur en dehors du champ d'application de la boucle (champ D'application du bloc), mais la variable let i n'est pas définie en dehors du champ d'application de la boucle.

"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);
40
répondu vlio20 2018-05-18 20:57:25
la source

let

Bloc de portée

les Variables déclarées à l'aide du mot-clé let ont une portée de bloc, ce qui signifie qu'elles ne sont disponibles que dans le bloc dans lequel elles ont été déclarées.

au niveau supérieur (en dehors d'une fonction)

au niveau supérieur, les variables déclarées à l'aide de let ne créent pas de propriétés sur l'objet 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

à l'intérieur d'une fonction

à l'Intérieur d'une d'une fonction (mais à l'extérieur d'un bloc), let a la même portée 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

à l'intérieur d'un bloc

Les Variables

déclarées à l'aide de let à l'intérieur d'un bloc ne peuvent pas être consultées à l'extérieur de ce bloc.

{
  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

à l'Intérieur d'une boucle

les Variables déclarées avec let dans les boucles peuvent être référencé uniquement à l'intérieur de cette boucle.

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.

boucles avec fermetures

Si vous utilisez let au lieu de var dans une boucle, à chaque itération, vous obtenez une nouvelle variable. Cela signifie que vous pouvez utiliser en toute sécurité une fermeture à l'intérieur d'une boucle.

// 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);
}

Temporelle zone morte

à cause de la zone morte temporelle , les variables déclarées en utilisant let ne peut pas être accéder avant qu'ils ne soient déclarés. Tenter de le faire entraîne une erreur.

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

Pas de re-déclarer

vous ne pouvez pas déclarer la même variable plusieurs fois en utilisant let . Vous ne pouvez pas non plus déclarer une variable en utilisant let avec le même identifiant qu'une autre variable qui a été déclarée en utilisant 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 est tout à fait similaire à let -il est à portée de bloc et a TDZ. Il y a cependant deux choses qui sont différentes.

Pas de re-affectation de

La Variable

déclarée par const ne peut pas être réattribuée.

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

Notez que cela ne signifie pas que la valeur est immuable. Ses propriétés peuvent encore être changé.

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

Si vous voulez avoir un objet immuable, vous devez utiliser Object.freeze() .

initialiseur requis

vous devez toujours spécifier une valeur lorsque vous déclarez une variable en utilisant const .

const a; // SyntaxError: Missing initializer in const declaration
38
répondu Michał Perłakowski 2017-05-23 15:34:53
la source
  • Variable Sans Levage

    let sera pas palan à l'ensemble du champ d'application de la bloquer dans lesquelles elles apparaissent. En revanche, var pouvait hisser comme ci-dessous.

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

    en fait, Per @Bergi, les deux var et let sont hissés .

  • Collecte Des Ordures

    Bloc de portée de let est utile se rapporte à des fermetures de collecte des déchets et de récupérer de la mémoire. Considérez,

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

    le click handler callback n'a pas besoin du tout de la variable hugeData . En théorie, après process(..) , la structure de données énorme hugeData pourrait être des ordures collectées. Toutefois, il est possible que certains moteurs JS devront encore conserver cette énorme structure, puisque la fonction click a une fermeture sur toute la portée.

    cependant, la portée de bloc peut rendre cette énorme structure de données aux ordures collectées.

    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 boucles

    let dans la boucle peut se lie de nouveau à chaque itération de la boucle, ce qui rend assurez-vous de lui attribuer de nouveau la valeur à partir de la fin de l'itération de la boucle précédente. Considérez,

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

    remplacer var par let

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

    parce que let crée un nouvel environnement lexical avec ces noms pour a) l'expression initialiseur b) chaque itération (précédemment à l'évaluation de l'expression increment), plus de détails sont ici .

20
répondu zangw 2017-05-23 15:34:53
la source

la différence principale est la différence scope , alors que let ne peut être disponible qu'à l'intérieur du scope il est déclaré, comme dans pour boucle, var peut être accédé en dehors de la boucle par exemple. De la documentation dans MDN (exemples également de MDN):

let vous permet de déclarer des variables qui sont limitées dans la portée de la bloc, énoncé ou expression sur lequel il est utilisé. Ceci est à la différence du mot-clé var , qui définit une variable globalement, ou localement à une fonction entière indépendamment de la portée du bloc.

les Variables déclarées par let ont pour champ d'application le bloc dans lequel elles sont définies, ainsi que dans les sous-blocs. Ainsi, let fonctionne très bien comme var . Principal la différence réside dans le fait que la portée d'une variable var est la totalité de la fonction d'enveloppe:

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

au niveau supérieur des programmes et des fonctions, let , contrairement à var , ne crée pas de propriété sur l'objet global. Par exemple:

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

lorsqu'il est utilisé à l'intérieur d'un bloc, permet de limiter la portée de la variable à bloc. Notez la différence entre var dont la portée est à l'intérieur de la fonction où elle est déclarée.

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

N'oubliez pas non plus sa fonctionnalité ECMA6, elle n'est donc pas encore totalement supportée, il est donc préférable de toujours la transporter vers ECMA5 en utilisant Babel, etc... pour plus d'informations sur la visite babel site web

17
répondu Alireza 2018-06-12 15:55:35
la source

voici un exemple à ajouter à ce que d'autres ont déjà écrit. Supposons que vous voulez faire un tableau de fonctions, adderFunctions , où chaque fonction prend un argument de nombre simple et retourne la somme de l'argument et l'index de la fonction dans le tableau. Essayer de générer adderFunctions avec une boucle en utilisant le mot-clé var ne fonctionnera pas de la façon dont quelqu'un pourrait naïvement s'attendre:

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

le processus ci-dessus ne génère pas le tableau désiré de fonctions parce que la portée de i s'étend au-delà de l'itération du bloc for dans lequel chaque fonction a été créée. Au lieu de cela, à la fin de la boucle, le i dans la fermeture de chaque fonction se réfère à la valeur de i à la fin de la boucle (1000) pour chaque fonction anonyme dans adderFunctions . Ce n'est pas du tout ce que nous voulions: nous avons maintenant un tableau de 1000 fonctions différentes en mémoire avec exactement le même comportement. Et si nous actualisons par la suite la valeur de i , la mutation affectera tous les adderFunctions .

Cependant, nous pouvons essayer à nouveau en utilisant le let mot clé:

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

cette fois, i est rebond sur chaque itération de la boucle for . Chaque fonction conserve maintenant la valeur de i au moment de la création de la fonction, et adderFunctions se comporte comme prévu.

maintenant, image mélangeant les deux comportements et vous verrez probablement pourquoi il n'est pas recommandé de mélanger les nouvelles let et const avec l'ancienne var dans le même script. Il peut en résulter une confusion spectaculaire du code.

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

Ne laissez pas cela vous arriver. Utilisez un linter.

NOTE: il s'agit d'un exemple d'enseignement destiné à démontrer le comportement var / let dans des boucles et avec des fermetures de fonctions qui seraient également facile à comprendre. Ce serait une façon terrible d'ajouter des nombres. Mais la technique générale de saisie de données dans des fermetures de fonctions anonymes pourrait être rencontrée dans le monde réel dans d'autres contextes. YMMV.

12
répondu abroz 2017-10-10 01:24:59
la source

la différence est dans la portée des variables déclarées avec chacun.

dans la pratique, il y a un certain nombre de conséquences utiles de la différence de portée:

  1. let les variables ne sont visibles que dans le bloc qui entoure le plus près ( { ... } ).
  2. let , les variables sont utilisables uniquement dans les lignes de code qui se produisent après la variable est déclarée (bien que ils sont hissés !).
  3. let variables ne peuvent pas être déclarées par un var ou let subséquents .
  4. Global let les variables ne sont pas ajoutées à l'objet global window .
  5. let , les variables sont facile à utiliser avec des fermetures (ils ne causent pas de conditions de course ).

les restrictions imposées par let réduisent la visibilité des variables et augmentent la probabilité que des collisions de noms inattendues soient détectées tôt. Cela rend plus facile de suivre et de raisonner sur les variables, y compris leur reachability (aide à la récupération de la mémoire inutilisée).

par conséquent, les variables let sont moins susceptibles de causer des problèmes lorsqu'elles sont utilisées dans les grandes entreprises. programmes ou indépendamment développé des cadres sont combinés de manière nouvelle et inattendue.

var peut encore être utile si vous êtes sûr de vouloir l'effet de liaison simple lors de l'utilisation d'une fermeture dans une boucle (#5) ou pour déclarer des variables globales visibles de l'extérieur dans votre code (#4). L'utilisation de var pour les exportations peut être supplantée si export migre hors de l'espace du transpondeur et dans le langage de base.

exemples

1. Usage interdit à l'extérieur du bloc d'enclos le plus proche: Ce bloc de code va jeter une erreur de référence parce que la deuxième utilisation de x se produit à l'extérieur du bloc où il est déclaré avec let :

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

en contraste, le même exemple avec var œuvres.

2. Pas d'usage avant la déclaration:

Ce bloc de code lancera un ReferenceError avant que le code puisse être lancé car x est utilisé avant qu'il ne soit déclaré:

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

en contraste, le même exemple avec var parses et court sans aucune exception de lancer.

3. Pas de déclaration: Le code suivant démontre qu'une variable déclarée avec let ne peut pas être déclarée plus tard:

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

4. Globals pas attaché à 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. Utilisation facile avec les fermetures: Les Variables déclarées avec var ne fonctionnent pas bien avec les fermetures à l'intérieur des boucles. Voici une boucle simple qui produit la séquence de valeurs que la variable i a à différents moments dans le temps:

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

plus précisément, cette sortie:

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

dans JavaScript, nous utilisons souvent des variables à un moment beaucoup plus tardif que lorsqu'elles sont créées. Lorsque nous le démontrons en retardant la sortie avec une fermeture passée à setTimeout :

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

... la sortie reste inchangée tant que nous restons avec let . En revanche, si nous avions utilisé var i à la place:

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

... la boucle produit inopinément "i est 5" cinq fois:

i is 5
i is 5
i is 5
i is 5
i is 5
11
répondu mormegil 2017-05-22 04:21:34
la source

peut présenter la différence entre les deux fonctions suivantes:

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
}
10
répondu Abdennour TOUMI 2016-11-26 19:18:38
la source

let est intéressant, parce qu'il nous permet de faire quelque chose comme ceci:

(() => {
    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++);
            }
        }
    }
})();

qui aboutit à un comptage [0, 7].

attendu que

(() => {
    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++);
            }
        }
    }
})();

ne compte que [0, 1].

9
répondu Dmitry 2016-11-26 19:34:26
la source

il apparaît également que, au moins dans Visual Studio 2015, Tapescript 1.5," var "permet plusieurs déclarations du même nom de variable dans un bloc, et" let " ne le fait pas.

cela ne générera pas d'erreur de compilation:

var x = 1;
var x = 2;

Ce sera:

let x = 1;
let x = 2;
6
répondu RDoc 2016-11-28 12:31:05
la source

var est une variable de portée mondiale (pouvant être hissée).

let et const est le bloc de portée.

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
5
répondu Moslem Shahsavan 2017-10-28 15:42:16
la source

si je lis les spécifications à droite, alors let heureusement peut également être utilisé pour éviter les fonctions auto invoking utilisés pour simuler des membres privés seulement - un modèle de conception populaire qui diminue la lisibilité du code, complique le débogage, qui ajoute aucune protection de code réel ou d'autres avantages - sauf peut-être satisfaire le désir de quelqu'un pour la sémantique, donc arrêter de l'utiliser. /coup de gueule

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

voir " Émulation d'interfaces privées

3
répondu Daniel Sokolowski 2016-10-14 08:01:10
la source

Certains hacks avec 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 et setter avec 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)
3
répondu zloctb 2016-11-26 19:44:48
la source

Lorsqu'On Utilise let

le mot-clé let attache la déclaration de variable à la portée de n'importe quel bloc (généralement une paire { .. } ) il est contenu dans. En d'autres termes, let détourne implicitement la portée de n'importe quel bloc pour sa déclaration de variable.

let les variables ne peuvent pas être consultées dans l'objet window parce qu'elles ne peuvent pas être consultées globalement.

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

Lorsqu'On Utilise var

var et les variables dans ES5 a des portées dans les fonctions signifiant les variables sont valides dans la fonction et non en dehors de la fonction elle-même.

Les variables

var peuvent être consultées dans l'objet window parce qu'elles ne peuvent pas être consultées globalement.

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

Si vous voulez en savoir plus continuer se lisant comme suit

l'une des questions les plus célèbres de l'entretien sur la portée peut également suffire l'utilisation exacte de let et var comme ci-dessous;

Lorsqu'on utilise let

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

c'est parce que lors de l'utilisation de let , pour chaque itération de boucle la variable est scopée et a sa propre copie.

lors de l'utilisation de var

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

c'est parce que lors de l'utilisation de var , pour chaque itération de boucle, la variable est scopée et a une copie partagée.

3
répondu Ankur Soni 2018-05-22 16:22:19
la source

soit c'est une partie de l'es6. Ces fonctions expliqueront facilement la différence.

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
}
2
répondu vipul jain 2017-12-17 13:47:31
la source

fonction VS bloc portée:

la principale différence entre var et let est que les variables déclarées avec var sont fonction scoped . Alors que les fonctions déclarées avec let sont bloc scopé . Par exemple:

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 avec var :

quand la première fonction testVar se fait appeler la variable foo, déclarée avec var , est encore accessible en dehors de la déclaration if . Cette variable foo serait disponible partout dans le cadre de la testVar fonction .

variables avec let :

quand la deuxième fonction testLet est appelée la barre de variables, déclarée avec let , est seulement accessible à l'intérieur de la déclaration if . Parce que les variables déclarées avec let sont bloc scoped (où un bloc est le code entre crochets bouclés E. g if{} , for{} , function{} ).

let variables n'obtenez pas hissé:

une autre différence entre var et let est les variables avec déclaré avec let ne vous faites pas hisser . Un exemple est la meilleure façon d'illustrer ce comportement:

variables let ne pas obtenir hissé:

console.log(letVar);

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

variables avec var do get hissé:

console.log(varVar);

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

Global let ne pas s'attacher à window :

une variable déclarée avec let dans le champ d'Application global (qui est le code qui n'est pas dans une fonction) n'est pas ajouté comme propriété sur l'objet global window . Par exemple (ce code est de portée mondiale):

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



quand doit-on utiliser let au lieu de var ?

utilisez let au-dessus de var chaque fois que vous le pouvez parce qu'il est simplement scopé plus spécifique. Ce réduit les conflits de nommage potentiels qui peuvent survenir en traitant un grand nombre de variables. var peut être utilisé quand vous voulez qu'une variable globale soit explicitement sur l'objet window (toujours considérer avec soin si cela est vraiment nécessaire).

2
répondu Willem van der Veen 2018-09-10 10:39:18
la source

auparavant, il n'y avait que deux portées en JavaScript, c'est-à-dire fonctionnelle et globale. Avec ' let " mot-clé JavaScript a maintenant introduit block-level variables.

pour avoir une compréhension complète du mot clé "let", ES6:’ let ' mot-clé pour déclarer variable en JavaScript aidera.

1
répondu Hitesh Garg 2016-11-26 19:27:58
la source

maintenant je pense qu'il y a une meilleure détermination de la portée des variables à un bloc d'énoncés en utilisant 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
}

je pense que les gens vont commencer à utiliser let ici après de sorte qu'ils auront une portée similaire en JavaScript comme D'autres langues, Java, C#, etc.

les personnes n'ayant pas une compréhension claire de la portée en JavaScript avaient l'habitude de faire l'erreur plus tôt.

Le

hissage n'est pas supporté par let .

avec cette approche, les erreurs présentes dans JavaScript sont supprimées.

Consultez ES6 En Profondeur: laissez et const pour mieux le comprendre.

1
répondu swaraj patil 2016-11-26 19:33:53
la source

cet article définit clairement la différence entre var, let et const

const est un signal que l'identifiant ne sera pas réattribué.

let , est un signal indiquant que la variable peut être réattribuée, tel qu'un compteur dans une boucle, ou un échange de valeur dans un algorithme. Il témoigne aussi de que la variable sera utilisée uniquement dans le bloc défini dans, ce qui n'est pas toujours l'ensemble de la fonction contenante.

var est maintenant le signal le plus faible disponible lorsque vous définissez une variable en JavaScript. La variable peut ou non être réaffectée, et variable peut ou ne peut pas être utilisé pour une fonction entière, ou juste pour le but d'un bloc ou d'une boucle.

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

1
répondu anandharshan 2017-04-30 20:11:41
la source

comme indiqué ci-dessus:

La différence est portée. var est scopé à la plus proche fonction le bloc et let est scopé au bloc le plus proche de l'enclos , qui peut être plus petit qu'un bloc de fonction. Les deux sont mondiales si en dehors de n'importe quel bloc.Voyons un exemple:

exemple1:

Dans mes deux exemples, j'ai une fonction myfunc . myfunc contient une variable myvar égale à 10. Dans mon premier exemple, je vérifie si myvar est égal à 10 ( myvar==10 ) . Si oui, je vais déclarer une variable myvar (maintenant j'ai deux variables myvar)en utilisant le mot-clé var et lui assigner une nouvelle valeur (20). Dans la ligne suivante j'imprime sa valeur sur ma console. Après le bloc conditionnel, j'affiche à nouveau la valeur myvar sur ma console. Si vous regardez la sortie de myfunc , myvar a une valeur égale à 20.

let keyword

Exemple2: Dans mon deuxième exemple, au lieu d'utiliser le mot-clé var dans mon bloc conditionnel, je déclare myvar en utilisant le mot-clé let . Maintenant quand j'appelle myfunc j'obtiens deux sorties différentes: myvar=20 et myvar=10 .

Donc, la différence est très simple je.e son champ d'application.

1
répondu N Randhawa 2018-08-13 17:02:08
la source

ECMAScript 6 a ajouté un mot-clé de plus pour déclarer les variables autres que "const"autre que "let".

le but principal de l'introduction de" let "et" const "sur" var " est d'avoir une portée de bloc au lieu de la portée lexicale traditionnelle. cet article explique très brièvement la différence entre" var "et" let "et il couvre également la discussion sur" const " .

0
répondu Gurucharan M K 2016-11-26 19:31:17
la source

vérifier ce lien En MDN

let x = 1;

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

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

console.log(x);
// expected output: 1
-2
répondu Nurlan 2018-05-18 10:27:41
la source

Autres questions sur javascript ecmascript-6 scope var let