Qu'est-ce qu'une variable globale (et est-ce sûr?)
Les variables globales sont la division: un raccourci inestimable ou un exemple dangereux de code bâclé? Parlons de ce qu'ils font, de ce pour quoi ils sont bons et pourquoi vous devriez être très prudent en les utilisant.
Sommaire
Qu'est-ce qu'une variable globale?
Un programme informatique est, essentiellement, une liste d'instructions à réaliser un ordinateur lorsque vous l'exécutez. Cependant, la plupart des programmes sont suffisamment complexes pour dépasser une simple liste un par un. Des structures comme les blocs, les fonctions et les définitions de classe peuvent vous aider à organiser votre code pour le rendre plus gérable.
Les fonctions sont l'outil le plus élémentaire que vous pouvez utiliser pour regrouper le code, isolant son comportement du reste de votre programme. Vous pouvez appeler une fonction à partir d'autres parties de votre code et réutiliser la même logique sans avoir à le dupliquer encore et encore.
Voici un exemple de fonction JavaScript qui utilise deux types de variables, un argument de fonction et une variable locale:
function factorial(x) {
let i; for (i = x - 1; i > 0; i--)
x *= i;
return x;
}
factorial(4);
L'argument de fonction, x, est automatiquement rempli de la valeur transmise à la fonction lorsqu'elle est appelée. Dans l'exemple ci-dessus, il prend la valeur 4.
La variable I est déclarée en utilisant le mot clé LET. Cela garantit qu'il s'agit d'une variable locale. Initialement, sa valeur n'est pas définie, avant que la boucle FOR attribue et modifie sa valeur.
Chaque variable est portée à la fonction factorielle; Aucun autre code ne peut lire ou écrire les valeurs de X ou i. Vous pouvez exécuter ce javascript dans la console de votre navigateur et confirmer que les variables X et I ne sont pas visibles en dehors de la fonction:
JavaScript prend également en charge les variables globales, qui ont une portée tout au long du programme. Voici une version alternative de la fonction factorielle qui vous oblige à définir une variable globale avant de l'appeler, plutôt que de passer un argument:
function factorial() {
let i; for (i = x - 1; i > 0; i--)
x *= i;
return x;
}
var x = 4;
factorial();
Il s'agit d'un type de fonction très peu orthodoxe, qui n'est pas pratique et uniquement utilisé ici pour démontrer une utilisation potentielle de variables globales. Cela fonctionne, mais c'est maladroit et plus gênant à utiliser. En fait, cette approche ressemble à l'ancien code d'assemblage, qui n'avait pas du tout le concept de fonctions.
La plupart des langages de programmation prennent en charge les variables globales, mais elles ont tendance à le faire de différentes manières. Par exemple, PHP utilise le mot-clé global pour accéder à une variable déclarée en dehors de toute fonction:
$a = 0;
$b = 0;function inc() {
global $a;
$a = 2;
$b = 2;
}
inc();
echo "a is $a and b is $bn";
Dans ce code, la fonction Inc utilise le mot-clé global pour accéder à la variable $ une variable déclarée au niveau supérieur. Lorsqu'il définit $ A, il modifie cette variable de niveau supérieur, donc la sortie confirme qu'elle a une valeur de 2. Cependant, $ b n'est pas déclaré global à l'intérieur Inc, donc la fonction modifie uniquement une variable locale – qui partage le même nom. La variable de niveau supérieur d'origine maintient sa valeur de 0.
Comment les variables globales peuvent-elles être utilisées à mauvais escient?
Le principal problème avec les variables globales est qu'ils rompent l'encapsulation, introduisant un potentiel généralisé pour les bogues. Considérez cet exemple:
var days = ( "Sunday", "Monday", "Tuesday", "Wednesday",
"Thursday", "Friday", "Saturday" );function day_name(number) {
return days(number);
}
La fonction day_name () accède à un tableau global pour retourner le nom d'un jour, donné par son numéro. Dans un petit programme, ce n'est probablement pas un problème, mais à mesure que la longueur et la complexité du programme se développent, les insectes peuvent prospérer.
Pour commencer, puisque la variable Days est globale, toute autre partie de la base de code pourrait la modifier. Le code suivant peut se produire n'importe où et modifier fondamentalement le comportement de Day_name:
days(5) = "I don't know when";
Dans les programmes plus importants, il peut être difficile et long d'identifier les parties du code qui utilisent ou modifient une variable globale.
Ce problème est encore plus grand si votre code est multi-thread. Avec plusieurs copies de votre code en cours d'exécution, il est beaucoup plus difficile de s'assurer qu'ils accèdent et modifient tous les variables globales sans se précipiter sur les orteils les uns des autres.
Ce code est également étroitement couplé, ce qui rend plus difficile le test. L'introduction d'une dépendance entre une fonction et une variable globale signifie que les deux doivent toujours coexister, et tester une fonction isolément devient un peu plus délicat.
En rapport
Qu'est-ce que les tests unitaires et pourquoi est-il important?
Les tests unitaires sont le processus d'écriture et d'exécution automatiquement des tests pour garantir que les fonctions que vous codez fonctionnent comme prévu.
Plus vous avez de variables globales, plus il est probable que des affrontements de nom se produisent. Pour JavaScript, il s'agit d'un problème particulier en raison de l'objet global. Dans un navigateur Web, toutes les variables globales sont stockées sous forme de propriétés de l'objet Window. Cela signifie qu'il est facile de déclarer une variable globale qui remplace une propriété de Window que votre code – ou celui de quelqu'un d'autre – est présent.
var alert = "no you don't";...
window.alert("Press OK to continue");
L'appel à Window.Alert () échouera avec une erreur car il s'agit maintenant d'une chaîne, pas d'une fonction. Bien que vous n'écrivez pas ce code intentionnellement, il est très facile de le faire accidentellement. Plus vous utilisez de variables globales, plus vous êtes susceptible de monter sur les orteils d'un autre code. Vous pouvez essayer d'éviter cela en utilisant des noms plus inhabituels pour vos variables globales, mais ce n'est qu'un plâtre collant; Il n'y a aucune garantie que votre code sera sûr.
Tous ces problèmes peuvent être plus répandus si vous utilisez des bibliothèques externes, selon la façon dont votre langue vous protège. JavaScript propose quelques protections ici, donc, si vous ne faites pas attention, les variables globales peuvent casser le code de bibliothèque que vous utilisez – ou vice versa.
Et à quoi servent les variables globales?
Les variables mondiales ne sont pas toutes mauvaises, cependant – en fait, elles sont parfois nécessaires, et les éviter à tout prix peut être coûteuse! Voici un exemple très raisonnable:
var debug = true;function do_something() {
let res = do_a_thing();
if (debug) {
console.debug("res was", res);
}
return res;
}
Cette approche du débogage peut être utile pendant le développement et les tests, et est parfaitement bien pour les programmes plus petits. Il est toujours vulnérable aux problèmes, cependant, en particulier le fait que toute partie du code peut modifier la valeur du débogage; c'est mutable. Pour éviter cela, il est de la meilleure pratique de déclarer une variable comme constante si vous voulez empêcher que sa valeur soit modifiée:
const SECONDS_IN_MINUTE = 60;
Il est important de noter qu'une constante en JavaScript n'est pas, à proprement parler, une mondiale. D'une part, il ne sera pas ajouté comme propriété de l'objet Window. Mais une constante que vous déclarez au niveau supérieur d'un script sera visible pour tout le code qui le suit.
En rapport
LET, VAR ET CONS: Définition des variables en javascript
La finalisation de l'ES6 en 2015 a apporté de nouvelles façons de définir les variables JavaScript.
Si vous vous retrouvez à utiliser des variables globales, vous pouvez également réduire la possibilité de problèmes en utilisant un seul objet global. Par exemple, au lieu de:
var color = (0, 0, 255);
var debug = false;
var days = 7;
...
Vous pouvez stocker les mêmes valeurs sur une carte globale:
var all_my_globals = {
color: (0, 0, 255),
debug: false,
days: 7,
...
};
Avec cette approche, vous venez d'ajouter un seul nom à l'espace de noms global, il y a donc moins de chances qu'il entre en conflit avec les autres, et il est plus facile de rechercher votre code pour trouver des utilisations de cette variable.
Enfin, la documentation est votre ami. Si vous devez utiliser des variables globales, assurez-vous qu'elles sont expliquées dans un commentaire, surtout si vous avez considéré une approche alternative mais que vous avez fini par le rejeter. Les noms de variables agissent également comme documentation, assurez-vous donc d'utiliser des noms clairs, concis et spécifiques qui expliquent l'objectif de chaque variable.