Comprendre les variables, la portée et le levage en JavaScript

introduction

LesVariables sont une partie fondamentale de nombreux langages de programmation et sont parmi les premiers et les plus importants concepts à apprendre pour les codeurs novices. Il existe un certain nombre de propriétés différentes de variables en JavaScript, ainsi que plusieurs règles à respecter lors de leur désignation. En JavaScript, il existe trois mots clés utilisés pour déclarer une variable -var,let etconst - et chacun affecte la manière dont le code interprétera la variable différemment.

Ce didacticiel couvrira ce que sont les variables, comment les déclarer et les nommer, et examinera également de plus près la différence entrevar,let etconst. Nous examinerons également les effets du levage et l’importance de la portée globale et locale pour le comportement d’une variable.

Comprendre les variables

Unvariable est un conteneur nommé utilisé pour stocker des valeurs. Une information que nous pourrions référencer plusieurs fois peut être stockée dans une variable pour une utilisation ou une modification ultérieure. En JavaScript, la valeur contenue dans une variable peut être n'importe quelJavaScript data type, y compris un nombre, une chaîne ou un objet.

Avant la spécification du langageECMAScript 2015 (ES6) sur laquelle le JavaScript d'aujourd'hui est basé, il n'y avait qu'une seule façon de déclarer une variable - à l'aide du mot clévar. En conséquence, la plupart des anciens codes et ressources d'apprentissage n'utiliseront quevar pour les variables. Nous allons passer en revue les différences entre les mots clésvar,let etconst dansits own section ci-dessous.

Nous pouvons utiliservar pour démontrer le concept de variable lui-même. Dans l'exemple ci-dessous, nous allonsdeclare une variable etassign une valeur.

// Assign the string value Sammy to the username identifier
var username = "sammy_shark";

Cette déclaration est composée de quelques parties:

  • La déclaration d'une variable à l'aide du mot-clévar

  • Le nom de la variable (ou identifiant),username

  • L'opération d'affectation, représentée par la syntaxe=

  • La valeur attribuée,"sammy_shark"

Nous pouvons maintenant utiliserusername dans le code. JavaScript se souviendra queusername représente la valeur de chaînesammy_shark.

// Check if variable is equal to value
if (username === "sammy_shark") {
  console.log(true);
}
Outputtrue

Comme mentionné précédemment, les variables peuvent être utilisées pour représenter tout type de données JavaScript. Dans cet exemple, nous allons déclarer des variables avec des valeurs chaîne, nombre, objet, booléen et null.

// Assignment of various variables
var name = "Sammy";
var spartans = 300;
var kingdoms = [ "mammals", "birds", "fish" ];
var poem = { roses: "red", violets: "blue" };
var success = true;
var nothing = null;

En utilisantconsole.log, nous pouvons voir la valeur contenue dans une variable spécifique.

// Send spartans variable to the console
console.log(spartans);
Output300

Les variables stockent des données en mémoire qui peuvent ensuite être consultées et modifiées. Les variables peuvent également être réaffectées et se voir attribuer une nouvelle valeur. L'exemple simplifié ci-dessous montre comment un mot de passe peut être stocké dans une variable, puis mis à jour.

// Assign value to password variable
var password = "hunter2";

// Reassign variable value with a new value
password = "hunter3";

console.log(password);
Output'hunter3'

Dans un programme réel, un mot de passe serait probablement stocké de manière sécurisée dans une base de données. Cependant, cet exemple illustre une situation dans laquelle nous pourrions avoir besoin de mettre à jour la valeur d'une variable. La valeur depassword était dehunter2, mais nous l'avons réaffectée àhunter3 qui est la valeur que JavaScript reconnaît à partir de ce point.

Variables de dénomination

Les noms de variables sont appelésidentifiers en JavaScript. Nous avons discuté de plusieurs règles de dénomination des identificateurs dansUnderstanding Syntax and Code Structure in JavaScript, résumées ici:

  • Les noms de variable ne peuvent être composés que de lettres (a-z), de chiffres (0-9), de symboles de signe dollar ($) et de traits de soulignement (_)

  • Les noms de variables ne peuvent contenir aucun caractère d'espacement (tabulation ou espace)

  • Les nombres ne peuvent pas commencer le nom d'une variable

  • Il existe plusieursreserved keywords qui ne peuvent pas être utilisés comme nom de variable

  • Les noms de variables sont sensibles à la casse

JavaScript a également la convention d'utiliser la casse camel (parfois stylisée comme camelCase) dans les noms des fonctions et des variables déclarées avecvar oulet. C'est la pratique d'écrire le premier mot en minuscule, puis de mettre en majuscule la première lettre de chaque mot suivant, sans espace entre eux. La plupart des variables qui ne sont pas des constantes suivront cette convention, à quelques exceptions près. Les noms des variables constantes, déclarées avec le mot-cléconst, sont généralement écrits en majuscules.

Cela peut sembler beaucoup de règles à apprendre, mais il deviendra très vite une seconde nature pour écrire des noms de variables valides et conventionnels.

Différence entrevar,let etconst

JavaScript a trois mots-clés différents pour déclarer une variable, ce qui ajoute une couche supplémentaire de complexité à la langue. Les différences entre les trois sont basées sur la portée, le levage et la réaffectation.

Mot-clé Portée Levage Peut être réaffecté Peut être redéclaré

var

Portée de la fonction

Yes

Yes

Yes

let

Portée du bloc

No

Yes

No

const

Portée du bloc

No

No

No

Vous vous demandez peut-être lequel des trois vous devriez utiliser dans vos propres programmes. Une pratique communément acceptée consiste à utiliser le plus possibleconst etlet dans le cas de boucles et de réaffectation. En général,var peut être évité en dehors du travail sur du code hérité.

Portée Variable

Scope en JavaScript fait référence au contexte actuel du code, qui détermine l'accessibilité des variables à JavaScript. Les deux types d'étendue sontlocal etglobal:

  • Global variables sont ceux déclarés en dehors d'un bloc

  • Local variables sont ceux déclarés à l'intérieur d'un bloc

Dans l'exemple ci-dessous, nous allons créer une variable globale.

// Initialize a global variable
var creature = "wolf";

Nous avons appris que les variables peuvent être réaffectées. En utilisant la portée locale, nous pouvons en réalité créer de nouvelles variables avec le même nom qu'une variable dans une portée externe sans modifier ou réaffecter la valeur d'origine.

Dans l'exemple ci-dessous, nous allons créer une variable globalespecies. La fonction contient une variable locale portant le même nom. En les envoyant à la console, nous pouvons voir en quoi la valeur de la variable est différente en fonction de l’étendue et la valeur initiale n’est pas modifiée.

// Initialize a global variable
var species = "human";

function transform() {
  // Initialize a local, function-scoped variable
  var species = "werewolf";
  console.log(species);
}

// Log the global and local variable
console.log(species);
transform();
console.log(species);
Outputhuman
werewolf
human

Dans cet exemple, la variable locale estfunction-scoped. Les variables déclarées avec le mot clévar ont toujours une portée fonction, ce qui signifie qu'elles reconnaissent les fonctions comme ayant une portée distincte. Cette variable de portée locale n'est donc pas accessible à partir de la portée globale.

Cependant, les nouveaux mots cléslet etconst sontblock-scoped. Cela signifie qu'une nouvelle portée locale est créée à partir de tout type de bloc, y compris les blocs fonctionnels, les instructionsif et les bouclesfor etwhile.

Pour illustrer la différence entre les variables de fonction et de bloc, nous allons affecter une nouvelle variable dans un blocif en utilisantlet.

var fullMoon = true;

// Initialize a global variable
let species = "human";

if (fullMoon) {
  // Initialize a block-scoped variable
  let species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a human.

Dans cet exemple, la variablespecies a une valeur globalement (human) et une autre valeur localement (werewolf). Si nous devions utiliservar, cependant, il y aurait un résultat différent.

// Use var to initialize a variable
var species = "human";

if (fullMoon) {
  // Attempt to create a new variable in a block
  var species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);
OutputIt is a full moon. Lupin is currently a werewolf.
It is not a full moon. Lupin is currently a werewolf.

Dans le résultat de cet exemple, la variable globale et la variable de portée de bloc se retrouvent avec la même valeur,werewolf. En effet, au lieu de créer une nouvelle variable locale avecvar, vous réaffectez la même variable dans la même portée. var ne reconnaît pasif comme faisant partie d'une nouvelle étendue différente. Il est généralement recommandé de déclarer les variables dont la portée est limitée aux blocs, car elles produisent un code moins susceptible de remplacer involontairement les valeurs des variables.

Levage

Dans la plupart des exemples jusqu'à présent, nous avons utilisévar àdeclare une variable, et nous avonsinitialized avec une valeur. Après avoir déclaré et initialisé, nous pouvons accéder à la variable ou la réaffecter.

Si nous essayons d'utiliser une variable avant qu'elle n'ait été déclarée et initialisée, elle retourneraundefined.

// Attempt to use a variable before declaring it
console.log(x);

// Variable assignment
var x = 100;
Outputundefined

Cependant, si nous omettons le mot-clévar, nous ne déclarons plus la variable, nous l'initialisons seulement. Il renverra unReferenceError et arrêtera l'exécution du script.

// Attempt to use a variable before declaring it
console.log(x);

// Variable assignment without var
x = 100;
OutputReferenceError: x is not defined

La raison en est due àhoisting, un comportement de JavaScript dans lequel les déclarations de variables et de fonctions sont déplacées vers le haut de leur portée. Puisque seule la déclaration réelle est hissée, pas l'initialisation, la valeur du premier exemple renvoieundefined.

Pour illustrer plus clairement ce concept, vous trouverez ci-dessous le code que nous avons écrit et comment JavaScript l’a interprété.

// The code we wrote
console.log(x);
var x = 100;

// How JavaScript interpreted it
var x;
console.log(x);
x = 100;

JavaScript a enregistréx en mémoire en tant que variable avant l'exécution du script. Comme il était encore appelé avant d'être défini, le résultat estundefined et non100. Cependant, cela ne provoque pas deReferenceError et arrête le script. Bien que le mot-clévar n'ait pas réellement changé d'emplacement desvar, il s'agit d'une représentation utile du fonctionnement du levage. Ce comportement peut cependant causer des problèmes, car le programmeur qui a écrit ce code s'attend probablement à ce que la sortie dex soittrue, alors qu'elle est à la placeundefined.

Nous pouvons également voir comment le levage peut conduire à des résultats imprévisibles dans l'exemple suivant:

// Initialize x in the global scope
var x = 100;

function hoist() {
  // A condition that should not affect the outcome of the code
  if (false) {
    var x = 200;
  }
  console.log(x);
}

hoist();
Outputundefined

Dans cet exemple, nous avons déclaréx comme étant100 globalement. Selon une instructionif,x pouvait devenir200, mais comme la condition étaitfalse, elle n'aurait pas dû affecter la valeur dex. Au lieu de cela,x a été hissé au sommet de la fonctionhoist() et la valeur est devenueundefined.

Ce type de comportement imprévisible peut potentiellement causer des bogues dans un programme. Puisquelet etconst ont une portée de bloc, ils ne seront pas levés de cette manière, comme indiqué ci-dessous.

// Initialize x in the global scope
let x = true;

function hoist() {
  // Initialize x in the function scope
  if (3 === 4) {
    let x = false;
  }
  console.log(x);
}

hoist();
Outputtrue

La déclaration en double des variables, qui est possible avecvar, générera une erreur aveclet etconst.

// Attempt to overwrite a variable declared with var
var x = 1;
var x = 2;

console.log(x);
Output2
// Attempt to overwrite a variable declared with let
let y = 1;
let y = 2;

console.log(y);
OutputUncaught SyntaxError: Identifier 'y' has already been declared

Pour résumer, les variables introduites avecvar ont le potentiel d'être affectées par le levage, un mécanisme en JavaScript dans lequel les déclarations de variables sont enregistrées en mémoire. Cela peut entraîner des variables non définies dans le code. L'introduction delet etconst résout ce problème en lançant une erreur lors de la tentative d'utilisation d'une variable avant de la déclarer ou de la tentative de déclaration d'une variable plus d'une fois.

Constantes

De nombreux langages de programmation comportent desconstants, qui sont des valeurs qui ne peuvent pas être modifiées ou changées. En JavaScript, l'identifiantconst est modelé sur les constantes, et les valeurs affectées à unconst ne peuvent pas être réaffectées.

Il est courant d'écrire tous les identifiantsconst en majuscules. Cela les distingue facilement des autres valeurs variables.

Dans l'exemple ci-dessous, nous initialisons la variableSPECIES en tant que constante avec le mot-cléconst. Essayer de réaffecter la variable entraînera une erreur.

// Assign value to const
const SPECIES = "human";

// Attempt to reassign value
SPECIES = "werewolf";

console.log(SPECIES);
OutputUncaught TypeError: Assignment to constant variable.

Étant donné que les valeurs deconst ne peuvent pas être réaffectées, elles doivent être déclarées et initialisées en même temps, ou généreront également une erreur.

// Declare but do not initialize a const
const TODO;

console.log(TODO);
OutputUncaught SyntaxError: Missing initializer in const declaration

Les valeurs qui ne peuvent pas changer en programmation sont appeléesimmutable, tandis que les valeurs qui peuvent être modifiées sontmutable. Bien que les valeurs deconst ne puissent pas être réaffectées, elles sont modifiables car il est possible de modifier les propriétés des objets déclarés avecconst.

// Create a CAR object with two properties
const CAR = {
    color: "blue",
    price: 15000
}

// Modify a property of CAR
CAR.price = 20000;

console.log(CAR);
Output{ color: 'blue', price: 20000 }

Les constantes sont utiles pour faire comprendre à votre futur et aux autres programmeurs travaillant sur un projet avec vous que la variable prévue ne doit pas être réaffectée. Si vous prévoyez qu'une variable peut être modifiée à l'avenir, vous voudrez probablement utiliserlet pour déclarer la variable à la place.

Conclusion

Dans ce tutoriel, nous avons expliqué ce qu'est une variable, les règles de nommage d'une variable et comment réaffecter des valeurs de variable. Nous avons également découvert la portée et le levage, certaines des limitations du mot-clé originalvar, ainsi que la façon dontlet etconst corrigent ces problèmes.

Pour comparer la manière dont les variables sont utilisées dans d'autres langues, vous pouvez lire notre tutoriel à l'adresse suivante: «https://www.digitalocean.com/community/tutorials/how-to-use-variables-in-python-3[Comment utiliser les variables dans Python 3]. ”