Sont les variables déclarées à laisser ou const pas hissé dans ES6?
J'ai été jouer avec ES6 pendant un certain temps et j'ai remarqué que, bien que les variables déclarées avec var
sont hissés comme prévu...
console.log(typeof name); //undefined
var name = "John";
...les variables déclarées avec let
ou const
semblent avoir quelques problèmes avec levage:
console.log(typeof name); //ReferenceError
let name = "John";
et
console.log(typeof name); //ReferenceError
const name = "John";
Est-ce à dire que les variables déclarées avec let
ou const
ne sont pas hissé? Ce qui se passe vraiment ici? Quelle est la différence entre let
et const
dans cette affaire?
Vous devez vous connecter pour publier un commentaire.
@thefourtheye est correct de dire que ces variables ne peut pas être consulté avant qu'ils ne soient déclarés. Cependant, il est un peu plus compliqué que cela.
Toutes les déclarations (
var
,let
,const
,function
,function*
,class
) sont "hissé" en JavaScript. Cela signifie que si un nom est déclaré dans un champ, dans le champ d'application de l'identifiant sera toujours la référence de cette variable:C'est vrai à la fois pour la fonction et les domaines de bloc1.
La différence entre
var
/function
/function*
déclarations etlet
/const
/class
déclarations est le initialisation.Les anciens sont initialisées avec
undefined
ou l' (générateur) fonction lorsque la liaison est créée au-dessus de la portée. Le lexicalement les variables déclarées cependant rester non initialisée. Cela signifie qu'unReferenceError
exception est levée lorsque vous essayez d'y accéder. Il n'en sera que initialisé lorsque lelet
/const
/class
instruction est évalué, tout ce qui est avant (ci-dessus) qui est appelée la temporelle de la zone morte.Avis qu'un
let y;
déclaration initialise la variable avecundefined
commelet y = undefined;
aurait.La temporelle zone morte n'est pas syntaxique, l'emplacement, mais plutôt la temps entre la variable (champ d'application) la création et l'initialisation. Ce n'est pas une erreur de référence de la variable dans le code ci-dessus la déclaration tant que le code n'est pas exécuté (par exemple une fonction du corps ou tout simplement du code mort), et il va lever une exception si vous accéder à la variable avant de l'initialisation, même si l'accès à code est ci-dessous la déclaration (par exemple, dans un hissé déclaration de fonction est appelé trop tôt).
Non, ils fonctionnent de la même aussi loin que de levage est considéré. La seule différence entre eux est que un
const
fourmi doit être et ne peut être attribué à l'initialiser le cadre de la déclaration (const one = 1;
, à la foisconst one;
et, plus tard, des réaffectations commeone = 2
ne sont pas valides).1:
var
déclarations sont encore en travaillant uniquement sur le niveau de la fonction, bien sûrvar
).let foo = () => bar; let bar = 'bar'; foo();
illustre toutes les déclarations sont hissés en effet, même mieux, car il n'est pas évident en raison temporelle de la zone morte.const
commelet
est un défaut de conception. Dans un champ,const
doit avoir été faite pour être hissé et juste-à-temps-initialisé quand il est consulté. Vraiment, ils devraient avoir unconst
, unlet
, et un autre mot-clé qui permet de créer une variable qui fonctionne comme un "readonly"let
.lazy const
mot-clé - qui est une très bonne idée, mais un peu ésotérique et l'évaluation de l'ordre de moins en moins évident. Peu importe, la conception des discussions sont hors-sujet ici, vous pourriez voulez à la tête de plus de mail.mozilla.org/listinfo/es-discuss pour queundefined
ou l' (générateur de fonction)". Une idée de comment je peux améliorer le libellé?let
variables sont hissés au sommet de leur champ d'application. Je n'ai pas d'erreurs de référence.{ a = 5; console.log(a); let a; }
Ce lèveUncaught ReferenceError: Cannot access 'a' before initialization
Ne veut pas dire laisser n'est pas hissé?a
dansa = 5
n'a rien à voir, mais comme expliqué, il n'est pas initialisé jusqu'à ce que lelet a;
est évaluée, et l'utilisation de la variable avant qu' - y compris des affectations - provoque une exception.Citant ECMAScript 6 (ECMAScript 2015) de la spécification,
let
etconst
déclarations section,Donc, pour répondre à votre question, oui,
let
etconst
palan, mais vous ne pouvez pas y accéder avant la déclaration est évaluée au moment de l'exécution.ES6
introduitLet
variables qui vient avecblock level scoping
. Jusqu'à ce queES5
nous n'avons pasblock level scoping
, de sorte que les variables qui sont déclarées à l'intérieur d'un bloc sont toujourshoisted
au niveau de la fonction de cadrage.Fondamentalement
Scope
se réfère à l'endroit où dans votre programme de vos variables sont visibles, ce qui détermine l'endroit où vous êtes autorisé à utiliser les variables que vous avez déclaré. DansES5
nous avonsglobal scope,function scope and try/catch scope
, avecES6
nous avons également d'obtenir le bloc de niveau portée par l'aide de la Laisser.var
mot-clé, il est connu de l'ensemble de la fonction à partir du moment où elle est définie.Lorsque vous définissez une variable avec
let
déclaration c'est seulement connu dans le bloc défini.Si vous exécutez le code, vous pouvez voir la variable
j
est connue uniquement dans leloop
et pas avant et après. Pourtant, notre variablei
est connu dans leentire function
à partir du moment où elle est définie à partir.Il y a un autre grand avantage en utilisant le laisser comme il crée un nouvel environnement lexical et se lie également des frais de valeur plutôt que de garder un vieux de référence.
La première
for
boucle toujours imprimer le dernier valeur, aveclet
il crée un nouveau champ d'application et de lier les frais des valeurs de l'impression nous1, 2, 3, 4, 5
.Venir à
constants
, il fonctionne essentiellement commelet
, la seule différence est que leur valeur ne peut pas être changé. Dans les constantes mutation est permis, mais réaffectation n'est pas autorisé.Si une constante référence à un
object
, il va toujours se référer à laobject
mais laobject
lui-même peut être modifié (si elle est sujette au changement). Si vous désirez avoir une immuableobject
, vous pouvez utiliserObject.freeze([])
De MDN web docs:
Dans ECMAScript 2015,
let
etconst
sont hissés mais pas initialisé. Référencement de la variable dans le bloc avant la déclaration de la variable des résultats dans unReferenceError
parce que la variable est dans un "temporelle zone morte" depuis le début de la bloquer jusqu'à ce que la déclaration est traitée.