JavaScript : ce monde étrange et merveilleux
JavaScript : Bonnes pratiques et situations incongrues
Parfois, dans le joyeux open-space de DonkeyCode, entre deux rédactions de lignes de code, des questions existentielles s'imposent à nous.
Codeur anonyme : "Dites-donc les Donkeys : pourquoi doit-on mettre des accolades en JS pour être un gentil codeur ? Ce serait plus rapide sans eux, tout de même ! Et puis tiens, pourquoi trois signes égal ?"
Tandis que je sortais mon étendard de défenseur de code style et que certains préparaient des coktails MoloCodes, je me suis stoppée : je sais que je dois le faire, oui mais pourquoi ?
Ce moment très inspirant nous a permis le 8 mars 2018 de ressortir nos buzzers poussiéreux de notre grenier et d'organiser un Quiz : Bonnes pratiques JS et petites incongruités.
Bien évidemment, nous ne résistons pas à l'envie de vous le partager.
Amis codeurs, enjoy !
QUIZ JS : Bonnes pratiques et petites incongruités
Question 1
Où placer le tag <script/>
sur une page HTML ?
- Dans le head
- A la fin du body
- DTC
Réponse
Une page web est lue par le navigateur de haut en bas. La bonne pratique est donc d'insérer le code en dernier élement de la balise body. Ainsi tout le code dit "important" est interpreté en premier et le plus dynamique ensuite.
Bonne pratique
Toujours penser que le contenu est une information prioritaire de la page.
Question 2
Pourquoi ne faut-il pas utiliser la fonction eval()
?
- Elle entraine des problèmes de performance.
- Parce que c’est le diable qui l’a inventée
eval()
peut entrainer des problèmes de sécurité
Réponse
Selon vos croyances, vous pouvez répondre par les 3 propositions ! eval()
est une fonction qui exécute du JavaScript. Pour cela, elle démarre le compilateur. Ceci est très gourmand en termes de performance. Enfin, eval()
entraîne des problèmes de sécurité car elle permet d'exécuter du code passé en argument avec les passe-droits du navigateur.
Bonne pratique
eval()
est interdit car trop gourmand et dangereux.
Question 3
Quelle formule est interdite ?
setTimeout(() => { makeSomething() }, 100);
setTimeout(‘makeSomething()’);
setTimeout(makeSomething);
Réponse
Réponse 2 car un setTimeout
ou setInterval
appelle la fonction eval()
si l'argument passé est une chaine de caractère. Celle-ci, on vous l'accorde : il fallait le savoir :)
Bonne pratique
eval()
est interdit et en plus se cache partout ! ;)
Question 4
Que renvoie [1, 1, 1].map(parseInt)
?
[1, 1, 1]
[1, NaN, 1]
undefined
Réponse
La méthode map
passe trois arguments à sa callback : la valeur, l'index et le tableau original.
[1, 1, 1].map(parseInt)
equivaut donc à
[1, 1, 1].map((value, index, array) => parseInt(value, index, array)))
parseInt()
ne prend que deux arguments : une chaîne à parser et sa base, on peut donc oublier l'argument array
et se concentrer sur les deux premiers.
Pour l'index 0 : parseInt(1, 0)
est interprété comme parseInt(1)
et une base autodétectée (10) et retournera donc 1. En revanche, pour notre second élément parseInt
tente d'utiliser la base 1, qui est une aberration. Le résultat sera donc NaN
.
Résultat : [1, NaN, 1]
.
Bonne pratique
Il faut systématiquement utiliser parseInt
avec deux arguments. En dehors de l'exemple ci-dessus, l'auto-détection de la base est bien souvent néfaste.
Question 5
Que retourne ?
function boom() {
return
1 + 1;
}
Que retourne ?
function bim() {
return 1
+ 1;
}
Que retourne ?
var a = 2
function dababoum() {
return 1
1 + a ;
}
Réponse
JS interprète de manière différente une ligne suivant si elle se termine par un point-virgule ou non. Donc nos exemples :
boom()
=> undefined
bim()
=> 2
dababoum()
=> 1
Bonne pratique
Il faut toujours terminer sa ligne de code par un ;
pour une meilleure lisibilité (et vos copains développeurs vous remercieront !) et pour éviter des interprétations non voulues.
Question 6
Que se passe-t-il ?
if (error)
log('shit');
panic();
return response;
Réponse
Qu'une erreur surviennent ou non, la fonction panic()
sera toujours executée.
Bonne pratique
Il est nécessaire de toujours encadrer son code par des accolades. Ce type d'erreur arrive plus que l'on ne le croit.
Dans ce cas, le développeur A a voulu gagner un millième de seconde en ne mettant pas d'accolade.
Six mois plus tard, un développeur B ajoute des logs. Comme il doit placer 3 675 logs, il est fatigué et ne fait pas attention aux accolades absentes : c'est le drame !
Aussi soyez gentils, mettez des accolades !
Question 7
Que se passe-t-il ?
try {
alert(1);
} catch(error) {
alert(2);
} finally {
alert(3);
}
Réponse
Fenêtre de dialogue 1
puis une autre avec 3
Que se passe-t-il ?
try {
throw(1)
} catch(error) {
alert(2);
} finally {
alert(3);
}
Réponse
Fenêtre de dialogue 2
puis une autre avec 3
Et maintenant, que se passe-t-il ?
function tryAndReturn() {
try {
return 1;
} catch(error) {
return 2;
} finally {
return 3;
}
}
alert(tryAndReturn());
Réponse
return 3
: le bloc finally
est toujours exécuté.
Bonne pratique
Il est d'usage d'utiliser des finally pour exécuter du code en cas de succès ou d'erreur, par exemple pour terminer une connexion à une base de données ou fermer un fichier. Il faut juste faire attention au return
.
Question 8
Que se passe-t-il ?
alert("string" === typeof "");
alert("string" === typeof String(""));
alert("string" === typeof new String(""));
alert("donkeycode" === String("donkeycode"));
alert("donkeycode" === new String("donkeycode"));
Réponse
"string" === typeof ""
=> true
"string" === typeof String("")
=> true
"string" === typeof new String("")
=> false
"donkeycode" === String("donkeycode")
=> true
"donkeycode" === new String("donkeycode")
=> false
new String()
change le typage : le resultat sera un object
Bonnes pratiques
Il est recommencé en JS d'appliquer le triple égal pour garantir le typage d'une variable.
Néanmoins il faut faire attention de ne pas instancier les types de base JS car la variable finira avec un type Object
.
Question 9
Que se passe-t-il ?
const arr = [0, 1, 2];
alert(arr.length);
Réponse Breaking news : 2
!
Et que se passe-t-il ?
const arr = [0, 1, 2];
arr[10] = 10;
alert(arr.length);
Réponse 11
! En JS, quand on définit une valeur à un index de tableau, sa taille est modifiée.
Par ailleurs la méthode map
ne prend en compte que les éléments associés à une valeur (y compris undefined
) : avec arr.map(a => console.log(a));
on verra 0, 1, 2 et 10. Les autres index sont empty
Bonne pratique
On évite de modifier un élément d'un tableau dont l'index est supérieur à la longueur de celui-là.
Conclusion
- Un script dans le body, ce n'est pas sale ! Il faut penser priorisation d'information
eval()
est à éviter absoluement !setTimeout()
/setInterval()
: oui mais avec une fonction en argumentparseInt()
s'accompagne toujours de sa base- Celui qui ne met pas de point-virgule ni d'accolade ne travaille pas chez DonkeyCode !
- On n'utilisera plus
var
mais plutôt : const
en priorité :array
,object
, ouboolean
,string
,number
non changeantslet
pour les autres variables- Utilisation des
===
indispensable