Fonctions et portée des variables

Objectif

  • Comprendre les contraintes de portées des variables pour les fonctions.

Mise en situation

Nous connaissons bien le concept de portée d'une variable. Elle correspond à la zone du code source dans laquelle la variable est déclarée, et donc utilisable. Par défaut, les variables sont locales et ne peuvent être utilisées que dans le bloc de code où elles ont été déclarées.

Les fonctions étant des blocs de code comme les autres, les contraintes de portée des variables s'y appliquent de la même manière. Une variable définie dans une fonction n'est valable que dans cette fonction.

RappelPortée des variables

Lorsqu'on définit une variable, elle est associée au bloc où elle se déclarée et n'est visible que dans celui-ci. On parle ici de variable locale.

FondamentalPortée dans une fonction

Une variable définie dans une fonction ne sera accessible qu'à l'intérieur de celle-ci. En Python ce bloc est distinguable grâce à l'indentation et en JavaScript grâce aux accolades.

ExemplePortée des variables locales en JavaScript

1
/** JavaScript : function retournant le maximum d'une liste */
2
function maxList (localList) {
3
  let max = localList[0] // La variable max n'existe que durant l'exécution de la fonction
4
  for (let i = 0; i < localList.length; i++) {
5
    if (max < localList[i]) {
6
      max = localList[i]
7
    }
8
  }
9
  return max
10
}
11
12
console.log('Le maximum de la liste est ', maxList([2, 5, 10, 3]))

AttentionMême nom, portée différente

Il est possible définir dans une fonction une variable dont le nom est le même que celui d'une variable dans le programme qui l'appelle.

Si les deux variables sont locales à deux blocs différents, elles existent indépendamment et leurs valeurs ne sont pas conflictuelles.

1
/** JavaScript : function retournant le maximum d'une liste */
2
function maxList (localList) {
3
  let max = localList[0] 
4
  for (let i = 0; i < localList.length; i++) {
5
    if (max < localList[i]) {
6
      max = localList[i]
7
    }
8
  }
9
  return max
10
}
11
12
let max = maxList([2, 5, 10, 3]) // Cette variable max est différente de la variable max utilisée dans la fonction
13
console.log('Le maximum de la liste est ', max)
14

Rappel

En JavaScript, il est possible de définir une variable soit directement sans préfixe, soit avec var soit avec let.

Les syntaxes sans préfixe et avec var permettent de définir une variable qui persistera une fois le bloc fini, donc une variable globale. On évite d'utiliser les variables globales.

La syntaxe let permet de définir une variable qui sera détruite une fois le bloc terminé.

MéthodeDéclaration des variables dans les fonctions

Il faut toujours utiliser let ou const dans les fonctions JavaScript.

AttentionEffets de bord

Ne pas utiliser let pour définir une variable dans une fonction conduit à des effets de bord, il faut donc systématiquement définir les variables utilisées dans une fonctions pour les éviter.

En effet, une variable définie sans indication supplémentaire écrase les variables définies dans le code appelant.

Voici un exemple où une variable est modifiée sans que cela soit voulu.

La première version renvoie un résultat erroné. La seconde version corrige ce bug en ajoutant un let dans la première ligne de la fonction max_liste.

1
/** JavaScript : code ayant un problème avec la portée d'une de ses variables */
2
function maxList (localList) {
3
  // Sans let, on déclare une variable globale qui écrase la variable max existante
4
  max = localList[0]
5
  for (let i = 0; i < localList.length; i++) {
6
    if (max < localList[i]) {
7
      max = localList[i]
8
    }
9
  }
10
  return max
11
}
12
13
// On cherche le maximum d'une liste de listes d'entiers positifs
14
const listception = [
15
  [1, 12, 5],
16
  [4, 3, 10],
17
  [2, 7, 1, 9]
18
]
19
let max = 0
20
21
for (let i = 0; i < listception.length; i++) {
22
  const tempMax = maxList(listception[i])
23
  if (max < tempMax) {
24
    max = tempMax
25
  }
26
}
27
28
console.log(max) // Affichera 9 alors que le maximum est 12
1
/** JavaScript : code corrigeant l'effet de bord dû à la portée d'une variable */
2
function maxList (localList) {
3
  // Avec let, on déclare une variable locale à la fonction
4
  let max = localList[0] 
5
  for (let i = 0; i < localList.length; i++) {
6
    if (max < localList[i]) {
7
      max = localList[i]
8
    }
9
  }
10
  return max
11
}
12
13
// On cherche le maximum d'une liste de listes d'entiers positifs
14
const listception = [
15
  [1, 12, 5],
16
  [4, 3, 10],
17
  [2, 7, 1, 9]
18
]
19
let max = 0
20
21
for (let i = 0; i < listception.length; i++) {
22
  const tempMax = maxList(listception[i])
23
  if (max < tempMax) {
24
    max = tempMax
25
  }
26
}
27
28
console.log(max) // Affichera la bonne valeur

À retenir

  • Les contraintes de portée de variables sont valables également pour les fonctions.

  • En JavaScript, il est indispensable d'utiliser let pour définir des variables dans des fonctions pour éviter les effets de bord.

Stéphane Crozat, Marc Damie Paternité - Partage des Conditions Initiales à l'Identique