Existe-t-il une raison d'utiliser le mot clé «var» dans ES6?

261

Le guide de Babel sur ES6 dit:

letest le nouveau var.

Apparemment, la seule différence est que la varportée est affectée à la fonction actuelle , tandis que letle bloc actuel l’ est . Il y a quelques bons exemples dans cette réponse .

Je ne vois aucune raison d'utiliser le varcode ES6. Même si vous souhaitez étendre une variable donnée à l'ensemble de la fonction, vous pouvez le faire leten plaçant la déclaration en haut du bloc de fonction, ce que vous devriez faire de vartoute façon pour indiquer l'étendue réelle. Et si vous voulez inclure plus finement quelque chose dans un forbloc ou quelque chose, vous pouvez le faire aussi.

Donc, mon instinct est de cesser varcomplètement d’ utiliser lors de l’écriture de code ES6.

Ma question est la suivante: est-ce que je me trompe? Y at-il un cas légitime où varserait préférable sur let?

callum
la source
3
Je ne l'ai pas encore essayé (car je n'écris pas encore de code ES6), mais il semble qu'utiliser varun indicateur conscient du fait que cette variable est destinée à être étendue à l'ensemble de la fonction pourrait être une convention utile de "documentation automatique" .
jfriend00
10
Si vous placez une letdéclaration au sommet d'une fonction, je pense qu'il est tout aussi évident que vous vouliez l'étendre à l'ensemble de la fonction. Je ne pense pas que l’utilisation varrend le tout plus clair que simplement le localiser au sommet.
callum
11
Honnêtement, je pense que la seule raison varqui existe toujours est la compatibilité ascendante. Si ce n’était pas le cas, ils se seraient varcomplètement retirés , ou n’auraient jamais été introduits letau départ, changeant plutôt la sémantique de varce qu’elle aurait dû être depuis le début .
Jörg W Mittag
2
@RayToal Je suis d'accord avec 97% des propos de Kyle Simpson, mais ses raisons de continuer à utiliser varme semblent minces et insuffisantes pour justifier un troisième type de variable qui saute aux yeux. Vous pouvez définir une letfonction entière en la plaçant tout simplement en haut de la fonction, ce qui est beaucoup plus clair que l’écriture vardans un bloc (afin de l’extraire de ce bloc afin que vous puissiez ensuite l’utiliser en dehors du bloc). - bizarre). Il prévient que si vous définissez une letfonction comme une fonction, "c'est simplement la position qui indique la différence, plutôt que la syntaxe", mais je pense que c'est une bonne chose.
callum
2
@RayToal Moi aussi j'ai lu cet article (juste avant de lire cette discussion) et j'ai été vraiment déçu de son cas très faible var. les exemples qu’il donne à garder varsemblent artificiels - et sont basés sur de graves erreurs de codage. Il est bien mieux de se heurter à une erreur et d’être forcé de la corriger que d’utiliser des fonctions de langage qui laissent l’échapper! Ensuite, nous vous conseillons de tout inclure dans un essai / accrochage pour éviter les collisions? Le reste de ce lien est bon mais je ne suis pas du tout d'accord avec cela.
Mörre

Réponses:

217

Doug Crockford discute letà ce stade de son discours, " The Better Parts ".

Le fait est, letévite une source de malentendu, esp. pour les programmeurs avec des attentes définies par les langues avec block-scope. Une portée de fonctionvar a (elle déclare une variable visible dans toute la fonction) même si elle semble avoir une portée de bloc .

var pourrait peut-être encore être utile dans des cas extrêmes comme le code généré par une machine, mais j'étire fort là-bas

( constest également nouveau et a une portée de bloc. Après que let x = {'hi': 'SE'}vous puissiez réaffecter à x, alors que const y = xvous ne pouvez pas le faire y. C’est souvent préférable car cela empêche tout changement accidentel de votre vue. Mais pour être clair, vous pouvez toujours modifier l’objet y.hi = 'SO'à le congeler.)

De manière réaliste, votre impression est juste pour ES6: Adopter letet const. Arrêtez d'utiliser var.

(Dans une autre performance de « The Better pièces » , Doug dit pourquoi ===a été ajouté plutôt que de fixer les problèmes de== . ==Produit des résultats surprenants « », donc juste d' adopter ===.)


Un exemple révélateur

Mozilla Developer Network donne un exemple où varne fonctionne pas comme prévu. Leur exemple est réaliste: il définit les onclickgestionnaires dans une page Web. Voici un cas de test plus petit:

var a = [];
(function () {
   'use strict';
   for (let i = 0; i < 5; ++i) { // *** `let` works as expected ***
     a.push( function() {return i;} );
   }
} ());
console.log(a.map( function(f) {return f();} ));
// prints [0, 1, 2, 3, 4]

// Start over, but change `let` to `var`.
// prints [5, 5, 5, 5, 5]

varnous échoue car toutes les itérations de la boucle partagent la même ivariable à étendue de fonction, qui a la valeur une 5fois la boucle terminée.

Jerry101
la source
6
Il donne la même réponse sur l'adoption de === au lieu de ==. Le dernier est cassé mais le comité de normalisation ES n'a pas voulu le changer, alors ils ont ajouté === Je ne sais pas trop ce que cela signifie. ==n'est pas cassé du tout. Il peut simplement être défini comme suit: equality comparison using coersionCheck out github.com/getify/You-Dont-Know-JS/blob/master/…
AmmarCSE
13
@AmmarCSE, c'est un merveilleux document de 39 pages sur les coercitions implicites. Qui peut garder tout cela à l'esprit lors de la programmation? Doug voulait dire "cassé" comme résumé dans stackoverflow.com/a/359509/1682419 , bref, il est facile d’obtenir un bit lorsque les types de valeur varient plus que nous ne le pensions. Pouvez-vous prédire tout cela? [ '1.0' == 1.0, [1.0] == 1.0, [1.0] == '1.0', ['1.0'] == 1.0, [null] == '', [null] == 'null', '00' == false, [] == [], [] == 0, [] == '', [] == false, [] == true, [010] - [4] == ' 4.0 ', !![0], !![1], [0] == true, [1] == true, 1 == [[1]], 0 == [[0]], '1' == [1] ]
Jerry101
2
à droite, la plupart de ces exemples impliquent un opérande de tableau. Il est facile de comprendre le résultat lorsque vous examinez toString et son implémentation pour Objects . Toutefois, si c’est ce que l’on entend par cassé, je vois bien d’où il vient. :-)
AmmarCSE
3
pourquoi ne pas utiliser const chaque fois que ce n'est pas mutable - il suffit de demander? Je veux dire, le vrai choix , il n'est pas entre letet varmais plutôt entre let, varetconst
shabunc
4
varfonctionne comme prévu, mais pas combien de personnes attendent. C'est un bug de convivialité, pas un bug d'implémentation.
Jerry101
12

Si vous avez écrit du code correct, vous pourrez probablement transformer toutes les varinstructions en letinstructions sans aucun changement sémantique.

letest préférable car elle réduit la portée dans laquelle un identifiant est visible. Cela nous permet de déclarer en toute sécurité des variables sur le site de première utilisation.

constest préférable à let. Sauf si vous devez modifier une référence, utilisez une constdéclaration. Cela présente tous les avantages de letréduire la présence de variables unitarisées et de rendre le code généralement plus facile à raisonner. Si vous n'êtes pas sûr de devoir muter une référence, déclarez-la constjusqu'à ce que vous en ayez explicitement besoin.

Aluan Haddad
la source
5

Je ne pense pas nécessairement que vous ayez tort, mais l'utilisation de var est soumise à des restrictions. Essentiellement, ils letdevraient aider les développeurs à surmonter la stupidité de JavaScript, en particulier en ce qui concerne les conflits de noms. var, semble-t-il, a une portée plus large puisqu'il veut aller à la fonction de fermeture. Il y aura des moments où vous aurez besoin de var, comme lorsque vous avez besoin d'une variable temporaire pour être disponible dans le cadre d'un bloc à l'intérieur d'une fonction, sinon, préférer letvar aidera les développeurs aux conflits de noms. Sur une note plus légère, il est temps que l'ES6 soit introduit let.

curieux
la source
3
Un temp vardans un bloc est disponible dans toute la fonction, mais pas dans un bloc. C'est une caractéristique trompeuse.
Jerry101
1

J'ai tendance à être d'accord que seul "laisser" devrait être utilisé dans es6. AFIK, redéclarer un "let" génère une erreur (ce qui est bien), alors qu'avec "var", vous écrasez simplement la valeur (bien que le "mode strict" dans es5 s'en occupe également).

yar1
la source
-4

letsignifie "laisser variable égale". C'est une déclaration, en d'autres termes, une initialisation et une affectation.

Il existe par opposition à constce qui bien sûr signifie "constant" - ce qui est l'opposé de variable.

D'autres langues utilisent un préfixe pour l'objet réel au lieu de l'objet lors de sa déclaration (par exemple, defun raccourci pour "define function" - ce qui manque complètement le point de ce qui est "def".

Let ajoute cette incohérence sémantique à Javascript.

Logiquement, vous pouvez également laisser une constante égale à quelque chose, puisque le mot-clé "let" a pour tâche d'attribuer de la mémoire.

Le problème se pose parce que le varmot - clé a été introduit avant, il constétait donc compatible avec les versions antérieures.var ne veut pas nécessairement dire une variable. (Il pourrait également être utilisé pour attribuer une valeur constante.)

Par conséquent, l'introduction de letla mauvaise position. Pour s'assurer de ne pas oublier que lexicalement, c'est faux, ils ont également décidé de changer la portée lexicale de letvs var, de sorte que l'incohérence est notre principale préoccupation lors du débogage.

En d'autres termes, letexiste parce que les utilisateurs (c'est-à-dire les responsables de la langue) ont pensé que Javascript était trop cohérent, après avoir maîtrisé tous ses idiomes et ses idiosyncrasies, il désirait davantage.

Note latérale, varne fonctionne pas dans les blocs "flèche" si vous voulez traiter lesdits blocs comme des fermetures (car a varété introduit avant de traiter les blocs comme des fermetures), mais letsi.

Fijiaaron
la source
6
-1: pédant, inutile, principalement d'opinion.
Joel Mueller
Fijiaaron plaisante avec nous ici.
Jerry101
Je suis sensible à votre aversion pour la forme lexicale, letcar elle est en contradiction avec le ton d’autres mots clés de la même catégorie en JavaScript. Cela ne répond toujours pas à la question et n’est pas particulièrement bien exprimé. Downvoted
Aluan Haddad
3
letCe ne sont pas seulement les développeurs qui désirent plus de complexité. C'est en fait intuitivement plus compréhensible, car lorsque vous bouclez et fermez sur vars, la fermeture conserve la dernière valeur de la variable, mais lorsque vous effectuez la même opération, chaque fermeture de la boucle a sa propre valeur, l'exemple de @ Jerry101 ci
TKoL