javascript eval : une mauvaise pratique ?

 

Nombreux sont les développeurs qui utilisent la fonction javascript eval qui permet d’évaluer du code javascript dans une chaine de caractères. Rares sont ceux qui savent que l’usage de cette fonction est une mauvaise pratique et est donc à proscrire. Je vous explique pourquoi.

En premier lieu, retenez l’adage « eval() is evil » [la fonction eval est démoniaque]. Il n’y a rien de plus parlant pour retenir que l’usage de la fonction javascript eval est à proscrire.

L’utilisation de eval() comporte des risques en termes de sécurité, le code exécutée de cette manière pourrait avoir été modifié.

C’est un antipattern commun surtout lorsqu’il s’agit d’une réponse JSON d’une requête Ajax. Dans ce cas, il conviendrait de valider la chaine de caractères (vérifier qu’il n’y a pas de code malveillant) avant toute exécution.

Vous pouvez utiliser les méthodes intégrées des navigateurs pour analyser la réponse JSON afin valider la chaine de caractères json avant tout usage avec la fonction eval(). Pour les navigateurs qui ne supportent pas JSON.parse() nativement, vous pouvez utiliser une bibliothèque de JSON.org.

Une meilleure pratique serait l’utilisation du new Function() similaire à eval() mais mieux sécurisée. L’avantage de cette méthode est le code évalué dans la nouvelle fonction Function() sera exécuté dans une fonction locale de sorte que les variables définies avec var dans le code en cours d’évaluation ne deviendront pas automatiquement des variables globales.

Une autre façon d’éviter les variables globales automatiques est d’encapsuler eval() dans une fonction anonyme autoexecutée.

Une petit exemple pour clarifier les choses, ou un seul cas vient polluer l’espace de noms global:

console.log(typeof un); // "undefined"
console.log(typeof deux); // "undefined"
console.log(typeof trois); // "undefined"

var jsstring = "var un = 1; console.log(un);";
eval(jsstring); // affiche "1" dans la console js

jsstring = "var deux = 2; console.log(deux);";
new Function(jsstring)(); // affiche "2" dans la console js

jsstring = "var trois = 3; console.log(trois);";
(function () {
eval(jsstring);
}()); // affiche "3" dans la console js

console.log(typeof un); // "number" -> défini via eval au grand jour
console.log(typeof deux); // "undefined"  -> défini via Function
console.log(typeof trois); // "undefined" -> défini via eval dans fonction autoexécutée

Une autre différence entre eval() et le constructeur de fonction est qu’eval() peut perturber la chaîne du scope alors que Function est circonscrit au contexte de la fonction: tout ce qui y est défini n’est pas exposé ou visible de l’extérieur. Peu importe où vous exécutez la fonction.

Dans l’exemple suivant, eval() peut accéder et modifier une variable dans sa partie externe alors que la fonction ne peut pas (notez également que l’utilisation de Function ou new Function est identique) :

 
(function () {
 var local = 1;
 eval("local = 3; console.log(local)"); // logs 3
 console.log(local); // logs 3
}());
(function () {
 var local = 1;
 Function("console.log(typeof local);")(); // logs undefined
 }());

 

Ça vous a aidé, partagez, commentez sans hésitation.

 

Si vous constatez des coquilles, ou avez des remarques, une autre solution ou encore souhaitez manifester votre satisfaction de ce tuto, commentez.

 

Si vous avez besoin d’aide, contactez moi toujours sans hésiter.

 

Posté dans javascript / html5  |  Laisser un commentaire

Répondre