Quelle est la différence entre utiliser "let" et "var" pour déclarer une variable en JavaScript?
27 réponses
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.
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.
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) })
}
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.
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
!
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
la réponse acceptée manque un point:
{
let a = 123;
};
console.log(a); // ReferenceError: a is not defined
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 .
voici un exemple pour la différence entre les deux (le support vient de démarrer pour chrome):
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);
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
-
Variable Sans Levagelet
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
etlet
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 variablehugeData
. En théorie, aprèsprocess(..)
, la structure de données énormehugeData
pourrait être des ordures collectées. Toutefois, il est possible que certains moteurs JS devront encore conserver cette énorme structure, puisque la fonctionclick
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
boucleslet
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
parlet
// 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 .
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
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.
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:
-
let
les variables ne sont visibles que dans le bloc qui entoure le plus près ({ ... }
). -
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 !). -
let
variables ne peuvent pas être déclarées par unvar
oulet
subséquents . - Global
let
les variables ne sont pas ajoutées à l'objet globalwindow
. -
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
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
}
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].
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;
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
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
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)
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.
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.
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
}
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 devar
?
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).
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.
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.
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
comme indiqué ci-dessus:
La différence est portée.
var
est scopé à la plus proche fonction le bloc etlet
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.
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.
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 " .