T: / Articles techniques / Javascript
Bonnes pratiques pour bien organiser le code de ses premiers algorithmes en Javascript.
En algorithmie, et en programmation d’une manière générale, adopter de bonnes pratiques est essentiel pour concevoir des algorithmes clairs, efficaces et faciles à comprendre. Cela facilite non seulement la lecture et la maintenance du code mais également la collaboration avec d’autres membres de son équipe.
Si tu as déjà beaucoup codé, cette liste te paraitra peut être « évidente » ou « triviale », mais il y a sans doute quelques éléments à découvrir et n’hésite pas à la voir comme une check list à garder en tête pendant que tu codes 😉
On alternera à chaque fois un bout de code et les explications qui vont avec (cet article étant écrit juste après les JO de Paris 2024, on va utiliser le thème du sport dans les exemples).
Voici donc 9 bonnes pratiques en Javascript :
// Mauvais exemple
let a = 90;
let b = 45;
let c = a - b;
// Bon exemple
const totalMatchTime = 90;
const halfTimeDuration = 15;
const effectivePlayTime = totalMatchTime - halfTimeDuration;
Explications :
En utilisant des noms de variables explicites, ton code devient plus lisible et facile à comprendre. Dans le bon exemple, les noms totalMatchTime, halfTimeDuration et effectivePlayTime décrivent clairement leur rôle, ce qui facilite la compréhension du code pour toi et pour les autres.
Il n’y a ni limite ni besoin d’abréviation lorsqu’on nomme une variable, une fonction, une classe, une méthode, etc.
// Mauvais exemple (utilisation de var)
function afficherJoueursVar() {
for (var i = 0; i < 11; i++) {
var joueur = "Joueur " + i;
console.log(joueur + " est sur le terrain.");
}
console.log("Dernier joueur traité : " + joueur); // Fonctionne, mais peut causer des problèmes
}
// Bon exemple (utilisation de let et const)
function afficherJoueursLetConst() {
for (let i = 0; i < 11; i++) {
const joueur = "Joueur " + i;
console.log(joueur + " est sur le terrain.");
}
console.log("Traitement terminé."); // 'joueur' n'est pas accessible ici, évitant les erreurs
}
afficherJoueursVar();
afficherJoueursLetConst();
Explications :
En Javascript, il est essentiel de choisir le bon mot-clé pour déclarer tes variables. Utiliser var
peut entraîner des problèmes de portée, car les variables déclarées avec var
sont accessibles en dehors du bloc où elles ont été définies. Dans le mauvais exemple, la variable joueur
reste accessible après la boucle for
, ce qui peut causer des comportements inattendus si le même nom de variable est utilisé ailleurs.
En revanche, let
et const
limitent la portée des variables au bloc dans lequel elles sont déclarées.
Utilise let
pour les variables dont la valeur peut changer, comme le compteur i
dans une boucle. Utilise const
pour les variables qui ne doivent pas être réassignées, comme joueur
dans cet exemple. Ainsi, tu évites les effets de bord et ton code devient plus sûr et plus facile à maintenir.
Abandonner var et adopter let
et const
te permet d’écrire du code plus propre et prévisible. Cela t’aide à prévenir les erreurs liées à la portée des variables et à rendre ton code plus lisible.
// Mauvais exemple (utilisation de while pour un nombre connu d'itérations)
let i = 0;
while (i < 11) {
console.log("Joueur numéro " + i);
i++;
}
// Bon exemple (utilisation de for pour un nombre connu d'itérations)
for (let i = 0; i < 11; i++) {
console.log("Joueur numéro " + i);
}
Explications :
Choisir la boucle appropriée rend ton code plus clair et plus efficace. Utilise une boucle for
lorsque tu connais à l’avance le nombre d’itérations. D’autant qu’une boucle while peut entrainer une boucle infinie !
Si tu maitrises les callables, tu peux aussi te passer des boucles en utilisant des fonctions comme map, filter ou reduce, mais attention à garder ton code lisible !
// Mauvais exemple
function checkQualification(score) {
if (score >= 10) {
console.log("Tu es qualifié.e pour la finale.");
} else {
console.log("Tu n'es pas qualifié.e.");
}
}
// Bon exemple
function checkQualification(score) {
if (score < 10) {
console.log("Tu n'es pas qualifié.e.");
return;
}
console.log("Tu es qualifié.e pour la finale.");
}
Explications :
En éliminant les else
inutiles, tu simplifies ton code et le rends plus lisible. En retournant ou en sortant de la fonction dès que possible, tu évites les conditions imbriquées et facilites la compréhension du flux logique.
// Mauvais exemple
let athlete1SpeedKmH = (100 / 9.58) * 3.6;
let athlete2SpeedKmH = (100 / 9.80) * 3.6;
// Bon exemple
function calculateSpeedKmH(distanceMeters, timeSeconds) {
return (distanceMeters / timeSeconds) * 3.6;
}
let athlete1SpeedKmH = calculateSpeedKmH(100, 9.58);
let athlete2SpeedKmH = calculateSpeedKmH(100, 9.80);
Explications :
En créant des fonctions pour les opérations répétitives, tu rends ton code plus modulable et facile à maintenir. Dans cet exemple, la fonction calculateSpeedKmH
te permet de calculer la vitesse en km/h de n’importe quel athlète en fonction de la distance et du temps, sans répéter le calcul à chaque fois !
Pas d’exemple de code ici.
Le but n’est pas de commenter pour commenter mais de prendre le temps d’écrire les commentaires avant de coder, pour expliciter la portion de code qui arrive, à quoi elle sert, comment elle fonctionne, etc. Cela permet d’écrire le plan du code à produire, avant de le produire !
J’en parle dans la vidéo : méthodologie pour résoudre un challenge de code (à partir de 4min27, c’est du PHP mais ça ne change rien au principe)
// Mauvais exemple (fonction monolithique)
function getTeamStatistics(team) {
let totalPoints = 0;
let totalAssists = 0;
team.forEach(player => {
totalPoints += player.points;
totalAssists += player.assists;
});
let averagePoints = totalPoints / team.length;
let averageAssists = totalAssists / team.length;
console.log(`Points moyens par joueur : ${averagePoints}`);
console.log(`Passes décisives moyennes par joueur : ${averageAssists}`);
}
// Bon exemple (division en sous-fonctions)
function calculateTotal(team, stat) {
return team.reduce((total, player) => total + player[stat], 0);
}
function calculateAverage(total, count) {
return total / count;
}
function displayTeamStatistics(averagePoints, averageAssists) {
console.log(`Points moyens par joueur : ${averagePoints}`);
console.log(`Passes décisives moyennes par joueur : ${averageAssists}`);
}
function getTeamStatistics(team) {
const totalPoints = calculateTotal(team, 'points');
const totalAssists = calculateTotal(team, 'assists');
const averagePoints = calculateAverage(totalPoints, team.length);
const averageAssists = calculateAverage(totalAssists, team.length);
displayTeamStatistics(averagePoints, averageAssists);
}
En divisant un problème complexe en sous-problèmes, tu rends ton code plus facile à gérer et à comprendre. Chaque fonction a une responsabilité spécifique, ce qui facilite les tests, car tu pourras tester les fonctions une par une et non tout le programme à la fois. C’est pareil pour la maintenance, tu vas pouvoir faire évoluer ou optimiser ton code portion par portion.
Tu peux retrouver des méthodes pour réfléchir au découpage d’un algorithme.
Pas d’exemple de code ici.
Le but est de rappeler que bien souvent, le diable se cache dans les détails ! Ou plutôt que les bugs se cachent dans les cas particuliers ! Alors prends le temps d’analyser ton code et de définir les cas principaux et, surtout, les cas particuliers qui te permettront de déterminer si ton code est correct ou non.
Par « cas », j’entends un ensemble de données cohérentes entre elles qui sont susceptibles d’être des paramètres d’entrée de ton code.
Et quand on parle de tests, on ne peut pas ne pas parler de tests unitaires. Donc n’hésite pas à découvrir ce que sont les tests unitaires et comment en réaliser en javascript (des contenus dédiés arrivent sur Tainix, en attendant, Google et ChatGPT sont tes amis 😉 )
// Mauvais exemple (code condensé et peu lisible)
players.forEach(p => { totalScore += (p.trophies > 2) ? p.points : 0; });
// Bon exemple (code clair et bien formaté)
let totalScore = 0;
players.forEach(player => {
if (player.trophies > 2) {
totalScore += player.points;
}
});
Explications :
L’exemple ici est un peu extrême ! Mais fais attention aux ternaires qui s’enchainent, aux conventions non respectées, aux variables mal nommées, etc. Sur l’instant, le code parait clair et intelligent… mais quand on revient dessus quelques jours plus tard, bien souvent on y comprend plus rien !
Cet article existe également dans ses versions PHP et Python.
Other content to discover