[Nouvelles fonctionnalités de ES6 · (1)] Laissez et const déclarer des variables dans les nouvelles commandes, ne soyez pas stupide var!

Préface: Les inconvénients des variables de déclaration var dans ES5

ES5 nous fournit en fait deux méthodes de déclaration de variables: les varcommandes et les functioncommandes. L'utilisation de functioncommandes pour déclarer des fonctions n'est pas abordée ici, nous comparons principalement les varcommandes.

Auparavant, nous avons expliqué en détail dans l'article de mise en route de JS varqu'il existe trois caractéristiques principales des variables de déclaration de commande:

  • Les variables peuvent être déclarées à plusieurs reprises;
  • Les déclarations de variables seront promues;
  • Aucune portée au niveau du bloc;

Ces trois caractéristiques font que l'écriture du code JS semble un peu «aléatoire» et pas assez standardisée, et une telle logique grammaticale est également contre-intuitive. Donnez deux exemples:

  1. La variable interne couvrira la variable externe
    avec le même nom: ci - dessous, nous vardéclarons une variable globale et numattribuons une valeur de 1, puis redéclarons la variable showdans le ifbloc de code de la portée de la fonction numet attribuons une valeur de 2:
var num = 1;

function show() {
    
    
  console.log(num);
  if (false) {
    
    
    var num = 2;
  }
}

show();


——————OUTPUT——————
undefined

Le résultat final de la showsortie de l'exécution de la fonction est undefined.
En effet, la varvariable déclarée n'a pas de portée au niveau du bloc et la deuxième redéclaration numsera promue au début de la fonction, couvrant la variable globale externe du même nom. À ce stade, le résultat de sortie doit être undefined. (Les trois caractéristiques sont reflétées dans un exemple)

  1. Les variables de boucle utilisées pour compter dans diverses structures de boucle seront divulguées en tant que variables globales: lorsque
    nous utilisons des structures de boucle, nous déclarerons une variable de contrôle de boucle (telle que i, j, k, etc.), mais après la fin de la boucle, elle ne disparaît pas , Fuite dans une variable globale.
for (var i = 0; i < 3; i++) {
    
    
  //...
}
console.log(i);


——————OUTPUT——————
2

Une meilleure approche est que nous voulons qu'il ne soit valide que dans le contrôle de boucle, et il échouera automatiquement après la fin de la boucle et n'affectera pas l'exécution des autres parties du code. À ce stade, nous devons utiliser les nouvelles letcommandes de notre ES6 .

1. Bases de Let et Const

1.1 Utilisation basique de let

letLes commandes sont de nouvelles commandes utilisées pour déclarer des variables dans la norme ES6. Sa mission est de remplacer les varcommandes, son utilisation est similaire var, mais elle compense varles défauts de conception.

La différence la plus fondamentale entre les deux est que la letcommande peut déclarer le bloc de code actuel en tant que portée de niveau bloc (détaillée dans les chapitres suivants), et letles variables déclarées par la commande ne sont valides que dans le bloc de code actuel.
(Le bloc de code est dans une paire d'accolades {})

{
    
    
  let a = 1;
  var b = 2;
}

a // ReferenceError: a is not defined.
b // 2

L'accès à la variable en dehors du bloc de code asera signalé une erreur non définie tout en utilisant vardes bvariables définies peut toujours être consulté.

Maintenant, avec la letcommande, vous pouvez résoudre le deuxième problème au début de cet article: le problème des fuites de variables de boucle. Nous utilisons l' instruction du forcompteur de boucle :ilet

for (let i = 0; i < 3; i++) {
    
    
  //...
}
console.log(i);


——————OUTPUT——————
// ReferenceError: i is not defined

La variable in'est pas accessible pour le moment .


❀ Développez un peu (1) ❀

letIl y a un autre point à noter lors de l'utilisation de commandes dans des boucles: les variables iseront redéclarées à chaque fois dans la boucle .

Regardons d'abord l'utilisation de la varvariable de boucle déclarée iet ajoutons une fonction de minuterie pour afficher cette variable de boucle dans chaque boucle i:

for(var i = 0; i < 3; i++) {
    
    
    setTimeout(function() {
    
    
        console.log(i);
    }, 1000);
}


——————OUTPUT——————
3
3
3

Trois 3 sont émis car la variable de boucle dans toute la boucle for est itoujours la même variable, et finalement la variable de fin de boucle ireçoit la valeur 2. Puis passez à la letcommande et sortez-la à nouveau:

for(let i = 0; i < 3; i++) {
    
    
    setTimeout(function() {
    
    
        console.log(i);
    }, 1000);
}


——————OUTPUT——————
0
1
2

Vous pouvez voir que le résultat de la sortie est le même que sans la fonction de minuterie. Cela est dû au fait que la variable iest de nouveau déclarée à chaque fois dans la boucle. La raison pour laquelle elle est sortie selon la logique normale est que le moteur JavaScript se souviendra de la valeur de la boucle précédente , Lors de l'initialisation des variables de ce tour, le icalcul est effectué sur la base du tour précédent.


❀ Développez un peu (2) ❀

La boucle for elle-même a une autre caractéristique spéciale - la partie où la variable de boucle est définie est une portée parent, et l'intérieur du corps de la boucle est une portée enfant distincte.

for (let i = 0; i < 3; i++) {
    
    
  let i = 'zevin';
  console.log(i);
}


——————OUTPUT——————
zevin
zevin
zevin

Il a été produit 3 fois zevin. Cela montre que les variables à l'intérieur du corps de la boucle iet les variables de la boucle ne isont pas dans la même portée et ont leurs propres portées distinctes.


1.2 Utilisation de base de const

constLa commande est utilisée pour déclarer une constante en lecture seule. Il doit être attribué au début de la déclaration et ne peut pas être modifié une fois déclaré.

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

const PI = 3.1415926;
PI = 3.14;
// TypeError: Assignment to constant variable.

❀ Développez-le ❀

L'essence de la commande const

Ce que la commande const garantit en fait n'est pas que la valeur de la variable ne peut pas être modifiée, mais que les données stockées dans l'adresse mémoire pointée par la variable ne peuvent pas être modifiées.

Pour les types de base de données simples (valeur numérique, chaîne, valeur booléenne), l'adresse mémoire pointée par la variable stocke la valeur elle-même, elle équivaut donc à la valeur de la variable qui ne peut pas être modifiée;

const obj = {
    
    };

// 可以添加属性
obj.name = 'zevin';
console.log(obj.name);
// zevin

// 让obj指向另一个对象就会报错
foo = {
    
    }; 
// TypeError: "obj" is read-only

Pour les types de données de référence (principalement des tableaux, des objets), l'adresse mémoire pointée par la variable enregistre l'adresse de référence, mais l'adresse de référence ne peut pas être modifiée. Pour le tableau, l'objet lui-même, nous pouvons toujours ajouter ou supprimer élément.


2. Nouvelle spécification de déclaration de variable ES6

Afin d'améliorer la situation dans une instruction ES5 var commande, mais aussi afin d'améliorer le langage normatif JS, ES6 propose les quatre nouvelles normes de déclaration de variables suivantes, letet les constcommandes sont applicables.

2.1 Portée au niveau du bloc

ES5 n'a qu'une portée globale et une portée fonctionnelle.Enfin, la portée au niveau bloc a été ajoutée à ES6. Utilisez letou la constvariable de commande d'action de niveau bloc déclarée dans une instruction uniquement lorsque le domaine est valide.

{
    
    
    let a = 1;
    if(true){
    
    
        const a = 2;
    };
    console.log(a);
}


——————OUTPUT——————
1

Le bloc de code est basé sur une paire d'accolades {}, qui peuvent être imbriquées arbitrairement sans affecter l'autre.

{
    
    {
    
    {
    
    {
    
    
  {
    
     const name = 'zevin' }
  console.log(name); 
  // 报错
}}}};

Le code ci-dessus utilise une portée de niveau bloc à cinq niveaux, chacune étant une portée distincte. La portée de quatrième niveau ne peut pas lire les variables internes de la portée de cinquième niveau.

2.2 Il n'y a pas de promotion variable

varLa variable déclarée par la commande sera promue au début du document ou au début de la fonction, c'est-à-dire que la variable peut être utilisée avant la déclaration, et la valeur est undefined. Et corrigé la grammaire dans le comportement ES6, letet la constcommande variable doit être déclarée dans une instruction après utilisation, sinon une erreur.

console.log(a);
console.log(b);
console.log(c);

var a = 1;
let b = 2;
const c = 3;


——————OUTPUT——————
undefined
ReferenceError: Cannot access 'b' before initialization
ReferenceError: Cannot access 'c' before initialization

2.3 Zone morte temporaire

ES6 clair que, si le bloc existe letet constcommande, ce bloc ces commandes déclarations de variables, dès le départ pour former une portée fermée. Si ces variables sont utilisées avant la déclaration, une erreur sera signalée. Ceci est grammaticalement appelé "zone morte temporelle" (TDZ pour faire court).

if (true) {
    
    
  // TDZ开始
  tmp = 'abc'; // ReferenceError
  console.log(tmp); // ReferenceError

  let tmp; // TDZ结束
  console.log(tmp); // undefined

  tmp = 123;
  console.log(tmp); // 123
}

Dans le code ci-dessus, avant que la letcommande déclare la variable tmp, tous appartiennent à tmpla "zone morte" de la variable .


❀ Développez-le ❀

L'émergence d'une «zone morte temporaire» signifie également que ce typeofn'est plus une opération qui ne rapportera jamais d'erreurs.

typeof a; // undefined
typeof b; // ReferenceError
const b = 1;

L' butilisation des variables constavant de déclarer les variables appartient à bla "zone morte", tant que l'utilisation de cette variable est une erreur. Par conséquent, l' typeofopérateur lancera une ReferenceErrorerreur.

Mais si une variable n'est pas du tout déclarée (variable a), typeofelle ne signalera pas d'erreur lorsqu'elle est utilisée undefined.


2.4 Les déclarations en double ne sont pas autorisées

ES6 n'autorise pas les déclarations multiples de la même variable dans la même portée.

if(true){
    
    
    var a = 1;
    let a = 2;
    const a = 3;
}
// SyntaxError: Identifier 'a' has already been declared

Par conséquent, de la même manière, la variable portant le même nom que le paramètre formel ne peut pas être utilisée letou constcommandée dans la fonction , mais elle le varpeut.

function func(num) {
    
    
  let num = 1;
  console.log(num);
}
func() 
// SyntaxError: Identifier 'num' has already been declared
function func(num) {
    
    
  var num = 1;
  console.log(num);
}
func() 
// 1

Étant donné que différentes étendues de niveau bloc ne s'affectent pas, nous pouvons définir des variables avec le même nom dans différentes étendues de niveau bloc. Ainsi, le code suivant ne signalera pas d'erreur:

function func(num) {
    
    
    var num = 1;
    if(true){
    
    
        let num = 2;
    }else{
    
    
        const num =3;
    }
  }
  func()

3. Extension: six façons de déclarer des variables dans ES6

ES5 ES6

fonction var
let
const
importer la
classe

ES6 en fait, quatre nouvelles méthodes de déclaration de variable: Cet article présente les letcommandes et la constcommande, suivi-introduit à nouveau les importcommandes et la classcommande. Couplé aux varcommandes et functioncommandes dans ES5 , il existe six façons de déclarer des variables dans ES6.

Je suppose que tu aimes

Origine blog.csdn.net/JZevin/article/details/108369123
conseillé
Classement