Tout le monde peut développer des scripts Javascript. Cependant, il existe des pièges ainsi que des astuces que souvent, les débutants ne connaissent pas. Lorsqu’ils sont connus, tous ces pièges ou astuces font gagner beaucoup de temps au développeur en lui évitant des anomalies liées à de mauvaises pratiques. Je vous montre en détail tous ces aspects de Javascript bien utiles si vous créez des jeux vidéos.

 

Prérequis

– un navigateur web de préférence Firefox ou Chrome;
– un éditeur de fichier comme notepad++.

 

Qu’est ce qu’un bloc d’instructions Javascript ?

Les développeurs le savent, mais je me permets de le rappeler pour ceux qui débutent dans ce langage.

En Javascript, un bloc d’instructions commence par une accolade ouvrante { suivi de votre script Javascript et se termine par une accolade fermante }.

{
 instruction1 Javascript
 .....
 instructionN Javascript
}

par exemple :

{
 let maVariable = 0;
 maVariable = 10 * maVariable;
}

On crée des blocs lorsque l’on :
– définit des fonctions;
– utilise une instruction if encapsulant plusieurs instructions;
– utilise une boucle (while, for, ….), etc….

 

Importance des mots clés let/var dans un script Javascript

Javascript étant très permissif, vous avez la possibilité de définir une variable de trois manières :

– sans le mot clé var :

function maFonction() {
 maVariable = 0;
 maVariable = 10 * maVariable;
}

– avec le mot clé var :

function maFonction() {
 for ( var maVariable = 0; maVariable<100; maVariable++ ) {
  maVariable = 10 * maVariable;
  console.log(maVariable);
 }
 console.log(maVariable);
}

– avec le mot clé let :

function maFonction() {
 for ( let maVariable = 0; maVariable<100; maVariable++ ) {
  maVariable = 10 * maVariable;
  console.log(maVariable);
 }
 console.log(maVariable); // variable indéfinie
}

Cependant dans le premier cas, la variable définie est considérée comme globale quelque soit le bloc dans lequel elle a été initialisée.

Elle sera donc visible dans toute votre page html. Non seulement elle sera visible dans tout votre code Javascript, mais aussi depuis tous les scripts intégrés à votre page comme des librairies ou encore des scripts intégrant par exemple de la publicité telle Google.

Dans le second cas, elle n’est visible que dans la fonction dans lequel elle est définie, elle est considérée comme locale à la fonction dans laquelle elle est définie.
Dans le troisième cas, elle n’est visible que dans le bloc dans lequel elle est définie, elle est considérée comme locale au bloc dans lequel elle est définie; en dehors du bloc elle n’existe pas.

 
[warning]Une variable définie sans les mots clé let/var est toujours globale. Une variable définie avec le mot clé let/var est locale au bloc/fonction dans lequel/laquelle elle est définie.[/warning]

 

Le problème lié à la portée des variables en Javascript

Imaginez que nous définissions dans un programme principale une variable i sans l’un des mots clé let ou var. Et que depuis ce programme principal, nous appelions une fonction qui utilise aussi une variable i non déclarée avec l’un des mots clé let ou var.

Il est fort probable que la variable i prenne des valeurs erratiques, sans explication à première vue et empêchant notre code de fonctionner correctement : que ce soit dans la fonction ou dans le programme principal.

La variable i a probablement subit les effets de la fonction qui utilise aussi une variable nommée i : ces deux variables ne sont pas considérés par Javascript comme deux variables distinctes mais comme une seule et même variable.

Illustration

L’exemple consiste à compter dix fois jusque 20 par le biais d’une boucle : nous définissons une fonction compterJusque20 que nous appelons 10 fois, sans utiliser le mot clé var :

<html>
 <script>
 let compterJusque20 = function() {
  for ( i=1 ; i<=20 ; i++) {
   document.write( "script externe i=" + i + "<br>" );
  }
 }
 
 // boucle de lancement de compterJusque20
 // on compte 10 fois jusque 20
 for ( i=1 ; i<=10 ; i++) {
  document.write( "comptage " + i + "<br>" );
  compterJusque20();
 }
 </script>
 <body>
 </body>
</html>

A l’exécution de ce petit bout de code, nous constatons que le comptage jusque 20 ne se fait qu’une seule fois au lieu de 10 fois.

En effet, que ce soit dans le code appelant la fonction compterJusque20 ou dans le code de cette même fonction, Javascript considère que la variable i est la même.
De ce fait, à la première exécution de la fonction compterJusque20, la valeur de la variable i atteint la valeur 20 à la fin de l’exécution de la fonction.

La valeur de i étant de 20, la boucle qui lance la fonction compterJusque20 s’arrête vue qu’elle utilise la variable i pour la boucle sensée lancer 10 fois la fonction compterJusque20.

Si maintenant, dans la fonction compterJusque20, nous utilisons l’un des mots clé let ou var pour définir la variable i, le comptage se fait correctement puisque la variable i définie ainsi dans la fonction est locale à cette fonction et n’est pas visible ailleurs :

<html>
 <script>
 let compterJusque20 = function() {
  for ( let i=1 ; i<=20 ; i++) {
   document.write( "script externe i=" + i + "<br>" );
  }
 }
 
 // boucle de lancement de compterJusque20
 // on compte 10 fois jusque 20
 for ( i=1 ; i<=10 ; i++) {
  document.write( "comptage " + i + "<br>" );
  compterJusque20();
 }
 </script>
 <body>
 </body>

Par contre, si nous utilisons l’un des mots clé let ou var uniquement dans la boucle de lancement de la fonction, cela ne change rien puisque une variable définie dans un bloc est visible depuis tous les sous blocs (blocs imbriqués).

Faut-il utiliser let ou var ?

Javascript a évolué avec de nouveaux mots clé avec notamment l’ajout d’un dédié à la déclaration de variable qui est le mot clé let.

Première différence :
– pour let la visibilité est limitée au bloc dans lequel la variable est déclarée, hors de ce bloc la variable n’existe pas;
– pour var la visibilité est limitée à la fonction, quelque soit le bloc dans laquelle la variable est déclarée, hors du bloc la variable existe, hors de la fonction la variable n’existe pas.

Deuxième différence :
var est auto-hissée: quelque soit l’endroit où est déclarée la variable avec var, lors de l’exécution, elle sera considérée comme une variable déclarée en début de fonction si elle l’est dans une fonction, en début de code si elle l’est en dehors d’une fonction.

 

La bonne pratique consiste donc à utiliser les mots clé Javascript let de préférence, a minima var à chaque fois que vous définissez une variable.

 

Le problème de l’intégration d’un code Javascript dans une page web existante

La problématique posée ici ne relève pas de notre fait mais plutôt d’une page contenant du code Javascript mal écrit avec, par exemple des variables non déclarées avec le mot clé var.

En effet, nous ne connaissons pas les variables utilisées par ce code existant. Et si par un malheureux hasard, nous venions à utiliser une variable dont le nom est identique à une variable déjà utilisée dans le code existant, qui plus est mal déclarée, nous risquerions d’avoir des effets induits incontrôlables, et surtout difficiles à debugger.

Les effets induits auront non seulement un effet sur votre code, et inversement un effet sur le code existant de la page. En bref, rien ne marche et nous ne savons pas pourquoi.

Une technique très simple permet d’isoler votre code :

 ( function() {
   ...le code Javascript isolé...
 }() );

Avec l’évolution de javascript ES6, la notation est simplifiée avec deux accolades:

{
}

L’intérêt de cette structure est qu’elle permet d’exécuter d’emblée, le code placé entre ( function() { et }() ); ou {} à l’instar d’un code javascript placé entre les balises . Ceci relève de la présence des parenthèses () placées juste après la définition de la fonction.

De plus elle permet d’isoler le code encapsulé de tout autre code javascript de la page : le code isolé dans cette structure n’est accessible que dans la structure et nulle part ailleurs : notre code n’est pas parasité et ne parasite pas.

Toutefois, il reste possible d’exposer volontairement le contenu isolé.

Illustration

L’exécution du code suivant montre que le contenu est d’emblée exécuté :

 ( function() {
  document.write("exécution du code isolé<br>");
 }());

ou

{
  document.write("exécution du code isolé<br>");
}

L’exécution suivante montre que la variable variableCodeIsole définie dans un bloc isolé (BI) n’est pas visible depuis l’extérieur du BI ; l’erreur Uncaught ReferenceError: variableCodeIsole is not defined est levée :

 ( function() {
  let variableCodeIsole = 10;
  document.write("exécution du code isolé<br>");
 }());
 document.write("variableCodeIsole=" + variableCodeIsole + "<br>");

ou

{
  let variableCodeIsole = 10;
  document.write("exécution du code isolé<br>");
}
document.write("variableCodeIsole=" + variableCodeIsole + "<br>");

Idem avec une fonction définie dans le BI (Uncaught ReferenceError: definieDansCodeIsole is not defined):

 ( function() {
  let variableCodeIsole = 10;
  document.write("exécution du code isolé<br>");
  
  let definieDansCodeIsole = function() {
   document.write("appel fonction code isolé<br>");
  }
 }());
 definieDansCodeIsole();

ou

{
  let variableCodeIsole = 10;
  document.write("exécution du code isolé<br>");
  
  let definieDansCodeIsole = function() {
   document.write("appel fonction code isolé<br>");
  }
}
definieDansCodeIsole();

De même qu’une fonction ou une variable définies dans un BI ne sont pas accessibles depuis un autre BI :

  ( function() {
  let variableCodeIsole = 1;
  document.write("exécution du code isolé 1<br>");
  
  let definieDansCodeIsole1 = function() {
   document.write("appel fonction code isolé 1<br>");
  }
 }());
 
 ( function() {
  let variableCodeIsole = 2;
  document.write("exécution du code isolé 2<br>");
  
  let definieDansCodeIsole2 = function() {
   document.write("appel fonction code isolé 2<br>");
  }
 
  definieDansCodeIsole1();
 }());

ou

{
  let variableCodeIsole = 1;
  document.write("exécution du code isolé 1<br>");
  
  let definieDansCodeIsole1 = function() {
   document.write("appel fonction code isolé 1<br>");
  }
}
 
{
  let variableCodeIsole = 2;
  document.write("exécution du code isolé 2<br>");
  
  let definieDansCodeIsole2 = function() {
   document.write("appel fonction code isolé 2<br>");
  }
 
  definieDansCodeIsole1();
}

Par contre, tout code défini en dehors de tout BI est accessible depuis tout BI.

La bonne pratique consiste donc à toujours encapsulé le code javascript entre ( function() { et }() ); ou entre {…}

 
Cette première partie sur le savoir indispensable Javascript s’achève. Volontairement, je n’ai pas parlé du mot clé const dédié à la déclaration de constantes.

Si vous connaissez d’autres bonnes pratiques en Javascript, partagez-les.