node - var let difference javascript




Quelle est la différence entre utiliser «let» et «var» pour déclarer une variable en JavaScript? (18)

let

Bloquer la portée

Les variables déclarées à l'aide du mot let 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

Dans une fonction (mais en dehors 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 en utilisant let dans un bloc ne sont pas accessibles en dehors 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

Dans une boucle

Les variables déclarées avec des boucles let in ne peuvent être référencées qu'à 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 des fermetures

Si vous utilisez let au lieu de var dans une boucle, vous obtenez une nouvelle variable à chaque itération. Cela signifie que vous pouvez utiliser en toute sécurité une fermeture dans 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);
}

Zone morte temporelle

En raison de la zone morte temporelle , les variables déclarées à l'aide de let ne sont pas accessibles avant leur déclaration. Tenter de le faire renvoie une erreur.

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

Pas de re-déclaration

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 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 assez similaire à let - il a une portée de bloc et a TDZ. Il y a cependant deux choses différentes.

Pas de réaffectation

La variable déclarée à l'aide de const ne peut pas être réaffecté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 modifiées.

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

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

L'initialiseur est requis

Vous devez toujours spécifier une valeur lorsque vous déclarez une variable à l'aide de const .

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

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

Quelles sont les différences? Quand faut let il utiliser sur var ?


Portée du bloc de fonction VS:

La principale différence entre varet letest que les variables déclarées avec varsont des fonctions étendues . Considérant que les fonctions déclarées avec letsont étendues au bloc . 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:

Lorsque la première fonction testVarest appelée, la variable foo, déclarée avec var, est toujours accessible en dehors de l' ifinstruction. Cette variable fooserait disponible partout dans le cadre de la testVar fonction .

variables avec let:

Lorsque la deuxième fonction testLetest appelée, la barre de variable, déclarée avec let, n'est accessible que dans l' ifinstruction. Étant donné que les variables déclarées avec letsont bloc scope (où un bloc est le code entre accolades , par exemple if{}, for{}, function{}).

let les variables ne sont pas levées:

Une autre différence entre varet letest les variables avec déclaré avec let ne pas être levé . Un exemple est le meilleur moyen d’illustrer ce comportement:

variables avec let ne pas se hisser:

console.log(letVar);

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

les variables avec se var faire hisser:

console.log(varVar);

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

Global letne s'attache pas à window:

Une variable déclarée avec letdans la portée globale (qui est un code qui n'est pas dans une fonction) n'est pas ajoutée en tant que propriété sur l' windowobjet global . Par exemple (ce code a une portée 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


Quand faut- letil utiliser var?

Utilisez letplus varchaque fois que vous pouvez , car il est tout simplement SCOPED plus spécifique. Cela réduit les conflits de noms potentiels pouvant survenir lors du traitement d'un grand nombre de variables. varpeut être utilisé quand vous voulez qu'une variable globale soit explicitement sur l' windowobjet (vérifiez toujours si cela est vraiment nécessaire).


Il y a quelques différences subtiles - let cadrage se comporter plus comme le champ variable varie dans plus ou moins d'autres langues.

par exemple, cela concerne le bloc englobant, ils n'existent pas avant leur déclaration, etc.

Toutefois, il est intéressant de noter que let n’est qu’un élément des implémentations JavaScript plus récentes et prend en charge divers degrés de navigateur .


La différence est la portée. var est délimité par le bloc de fonction le plus proche et let par le bloc le plus proche, qui peut être plus petit qu'un bloc de fonction. Les deux sont globaux s'ils sont en dehors d'un bloc.

De plus, les variables déclarées avec let ne sont pas accessibles avant d'être déclarées dans leur bloc englobant. Comme on le voit dans la démo, une exception ReferenceError sera renvoyée.

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:

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

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

Toutefois, les variables globales définies avec let ne seront pas ajoutées en tant que propriétés sur l'objet de window global, contrairement à celles définies avec var .

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

Une fonction:

Ils sont identiques lorsqu'ils sont utilisés de la sorte dans un bloc de fonction.

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 pour toute 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
}

Redéclaration:

En supposant que le mode strict soit appliqué, var vous permettra de déclarer de nouveau la même variable dans la même portée. Par contre, let laisserons 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.

La réponse acceptée manque un point:

{
  let a = 123;
};

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

Voici un exemple à ajouter à ce que d’autres ont déjà écrit. Supposons que vous souhaitiez créer un tableau de fonctions, adderFunctions , où chaque fonction prend un seul argument Number et renvoie 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 comme on pourrait s'y attendre naïvement:

// 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 de fonctions souhaité car 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 fait référence à la valeur de i à la fin de la boucle (1000) pour chaque fonction anonyme dans adderFunctions . Ce n’était pas ce que nous voulions du tout: nous avons maintenant en mémoire un tableau de 1000 fonctions différentes avec exactement le même comportement. Et si nous actualisons par la suite la valeur de i , la mutation affectera toutes les adderFunctions l' adderFunctions .

Cependant, nous pouvons essayer à nouveau en utilisant le mot let clé 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

Cette fois, i rebondis à chaque itération de la boucle for . Chaque fonction conserve désormais la valeur de i au moment de sa création et adderFunctions se comporte comme prévu.

Maintenant, en mélangeant les deux comportements, vous comprendrez probablement pourquoi il est déconseillé de mélanger les nouveaux let et const avec les plus anciennes var dans le même script. Cela peut donner lieu à un code extrêmement confus.

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: Ceci est un exemple pédagogique destiné à illustrer le comportement var/ leten boucles et avec des fermetures de fonctions faciles à comprendre. Ce serait un moyen terrible d'ajouter des chiffres. Mais la technique générale de capture de données dans des fermetures de fonctions anonymes peut être rencontrée dans le monde réel dans d'autres contextes. YMMV.


Voici une explication du mot let clé let avec quelques exemples.

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

Ce tableau sur Wikipedia indique les navigateurs prenant en charge Javascript 1.7.

Notez que seuls les navigateurs Mozilla et Chrome le prennent en charge. IE, Safari et potentiellement d'autres ne le font pas.



let peut également être utilisé pour éviter les problèmes de fermeture. Il lie une nouvelle valeur plutôt que de conserver une ancienne référence, comme indiqué dans les exemples ci-dessous.

DEMO

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

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

Chaque gestionnaire de clics fait référence au même objet car il n’ya qu’un seul objet compteur qui en contienne 6, de sorte que vous en obtenez six à chaque clic.

La solution de contournement générale consiste à envelopper cela dans une fonction anonyme et à passer i en argument. De tels problèmes peuvent également être évités maintenant en utilisant let place, comme indiqué dans le code ci-dessous.

DEMO (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) })
}

var est une variable de portée globale (pouvant être levée).

letet constest la portée du bloc.

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


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

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

let, est un signal indiquant que la variable peut être réaffectée, par exemple un compteur dans une boucle ou un échange de valeur dans un algorithme. Il indique également que la variable ne sera utilisée que dans le bloc dans lequel elle est définie, ce qui n’est pas toujours la fonction contenant la totalité.

varest 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 la variable peut ou ne peut pas être utilisée pour une fonction entière ou simplement pour les besoins d'un bloc ou d'une boucle.

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


Comme mentionné ci-dessus:

La différence est la portée. varest limité au bloc fonctionnel le plus proche et letau bloc englobant le plus proche , qui peut être inférieur à un bloc fonctionnel. Les deux sont globaux s'ils ne font pas partie d'un bloc. Voyons un exemple:

Exemple 1:

Dans mes deux exemples, j'ai une fonction myfunc. myfunccontient une variable myvarégale à 10. Dans mon premier exemple, je vérifie si myvarest égal à 10 ( myvar==10). Si oui, j’ai déclaré une variable myvar(j’ai maintenant deux variables myvar) en utilisant varmot-clé et lui attribue une nouvelle valeur (20). Dans la ligne suivante, j'imprime sa valeur sur ma console. Après le blocage conditionnel, j'imprime à nouveau la valeur de myvarsur ma console. Si vous regardez le résultat de myfunc, myvarsa valeur est égale à 20.

Exemple2: Dans mon deuxième exemple, au lieu d'utiliser varmot-clé dans mon bloc conditionnel, je déclare l' myvarutilisation d'un letmot-clé. Maintenant, quand j'appelle, myfuncj'ai deux sorties différentes: myvar=20et myvar=10.

La différence est donc très simple, c’est-à-dire sa portée.


Puissent les deux fonctions suivantes montrer la différence:

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
}


Maintenant, je pense qu'il est plus facile de définir la portée des variables d'un bloc d'instructions à l'aide de 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 here after afin d'avoir une portée similaire à JavaScript, à l'instar d'autres langages, Java, C #, etc.

Les personnes qui ne comprenaient pas bien la portée de JavaScript avaient l'habitude de faire l'erreur plus tôt.

Le levage n'est pas pris en charge avec let.

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

Reportez-vous à ES6 In Depth: let et const pour mieux le comprendre.


Quelques 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)

Vérifiez ce lien dans MDN

let x = 1;

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

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

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

let est une partie de es6. Ces fonctions expliqueront la différence de manière simple.

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
}




let