Get to know MDN better
Cette page a été traduite à partir de l'anglais par la communauté. Vous pouvez contribuer en rejoignant la communauté francophone sur MDN Web Docs.
Cette fonctionnalité est bien établie et fonctionne sur de nombreux appareils et versions de navigateurs. Elle est disponible sur tous les navigateurs depuis juillet 2015.
Attention : L'argument transmis à cette fonction est analysé dynamiquement et exécuté comme du JavaScript. Les API de ce type sont appelées points d'injection et peuvent être une source potentielle d'attaques par injection de script inter-sites (XSS).
Vous pouvez réduire ce risque en transmettant toujours des objets TrustedScript au lieu de chaînes de caractères et en imposant des types de confiance.
Voir Considérations de sécurité pour plus d'informations.
La fonction eval() évalue du code JavaScript représenté sous forme de chaîne de caractères et retourne sa valeur de terminaison. La source est analysée comme un script.
Une instance de TrustedScript ou une chaîne de caractères représentant une expression JavaScript, une instruction ou une suite d'instructions JavaScript. L'expression peut inclure des variables et des propriétés d'objets existants. Elle sera analysée comme un script, donc les déclarations import (qui ne peuvent exister que dans des modules) ne sont pas autorisées.
La valeur de terminaison du code évalué. Si la valeur de terminaison est vide, undefined est retournée. Si script n'est pas une instance de TrustedScript ou une chaîne de caractères primitive, eval() retourne l'argument inchangé.
Le paramètre script ne peut pas être analysé comme un script.
TypeErrorscript est une chaîne de caractères lorsque les types de confiance sont imposés par une CSP et qu'aucune politique par défaut n'est définie.
La méthode lance également toute exception qui survient lors de l'évaluation du code.
eval() est une propriété de fonction de l'objet global.
L'argument de la fonction eval() est une chaîne de caractères. Elle évalue la chaînes de caractères source comme un corps de script, ce qui signifie que les instructions et les expressions sont autorisées. Elle retourne la valeur de fin du code. Pour les expressions, il s'agit de la valeur à laquelle l'expression est évaluée. De nombreuses instructions et déclarations ont également des valeurs de fin, mais le résultat peut être surprenant (par exemple, la valeur de fin d'une affectation est la valeur affectée, mais la valeur de fin de let est indéfinie), il est donc recommandé de ne pas se fier aux valeurs de fin des instructions.
En mode strict, déclarer une variable nommée eval ou réassigner eval est une erreur de syntaxe (SyntaxError).
Si l'argument de eval() n'est pas une instance de TrustedScript ou une chaîne de caractères primitive, eval() retourne l'argument inchangé. Dans l'exemple suivant, passer un objet String au lieu d'une chaîne primitive fait que eval() retourne l'objet String au lieu d'évaluer la chaîne.
Pour contourner ce comportement de façon générique, vous pouvez contraindre l'argument en chaîne de caractères vous-même avant de le passer dans eval().
Il existe deux modes d'appel de eval() : l'évaluation directe et l'évaluation indirecte.L'évaluation directe, comme son nom l'indique, fait référence à l'appel direct de la fonction globale eval avec eval(…). Tout le reste, y compris l'invocation à l'aide d'une variable alias, à l'aide d'un accès membre ou d'une autre expression, ou à l'aide de l'opérateur de chaînage optionnel ?., est indirect.
L'évaluation indirecte peut être vue comme si le code était évalué dans une balise <script> séparée. Cela signifie :
L'évaluation indirecte fonctionne dans le contexte global plutôt que dans le contexte local, et le code évalué n'a pas accès aux variables locales dans le contexte où il est appelé.
Un eval indirect n'hérite pas de la rigueur du contexte environnant, et n'est en mode strict que si la chaîne source elle-même contient une directive "use strict".
En revanche, l'évaluation directe hérite de la rigueur du contexte appelant.
Les variables déclarées avec var et les déclarations de fonction seraient placées dans la portée environnante si la chaîne de caractères source n'était pas interprétée en mode strict — pour l'évaluation indirecte, elles deviennent des variables globales. S'il s'agit d'une évaluation directe dans un contexte en mode strict, ou si la chaîne de caractères source eval elle-même est en mode strict, alors les déclarations var et les déclarations de fonction ne « fuient » pas dans la portée environnante.
Les déclarations let et const à l'intérieur de la chaîne évaluée sont toujours limitées à ce script.
L'évaluation directe peut avoir accès à des expressions contextuelles supplémentaires. Par exemple, dans le corps d'une fonction, on peut utiliser new.target:
L'utilisation directe de eval() présente plusieurs problèmes :
Il existe de nombreux cas où l'utilisation de eval() ou de méthodes associées peut être optimisée, voire évitée.
Considérez ce code :
Le simple fait d'utiliser une évaluation indirecte et d'imposer le mode strict peut considérablement améliorer le code :
Les deux extraits de code ci-dessus peuvent sembler fonctionner de la même manière, mais ce n'est pas le cas ; le premier, qui utilise une évaluation directe, présente plusieurs problèmes.
Il est beaucoup plus lent, en raison de nombreuses inspections de portée. Remarquez c: new Map() dans la chaîne de caractères évaluée. Dans la version avec évaluation indirecte, l'objet est évalué dans la portée globale, il est donc sûr pour l'interpréteur de supposer que Map fait référence au constructeur global Map() au lieu d'une variable locale appelée Map. Cependant, dans le code utilisant l'évaluation directe, l'interpréteur ne peut pas supposer cela. Par exemple, dans le code suivant, Map dans la chaîne de caractères évaluée ne fait pas référence à window.Map().
Ainsi, dans la version eval() du code, le navigateur est contraint d'effectuer un appel de recherche coûteux pour vérifier s'il existe des variables locales appelées Map().
Si vous n'utilisez pas le mode strict, les déclarations var dans la source eval() deviennent des variables dans la portée environnante. Cela entraîne des problèmes difficiles à déboguer si la chaîne de caractères est acquise à partir d'une entrée externe, en particulier s'il existe déjà une variable portant le même nom.
L'évaluation directe peut lire et modifier les liaisons dans la portée environnante, ce qui peut entraîner la corruption des données locales par des entrées externes.
Lors de l'utilisation directe de eval, en particulier lorsque la source d'évaluation ne peut pas être prouvée comme étant en mode strict, le moteur — et les outils de compilation — doivent désactiver toutes les optimisations liées à la mise en ligne (inlining en anglais), car la source eval() peut dépendre de n'importe quel nom de variable dans son champ d'application environnant.
Cependant, l'utilisation indirecte de eval() ne permet pas de passer des liaisons supplémentaires autres que les variables globales existantes pour que la source évaluée puisse les lire. Si vous devez définir des variables supplémentaires auxquelles la source évaluée doit avoir accès, envisagez d'utiliser le constructeur Function().
Le constructeur Function() est très similaire à l'exemple d'évaluation indirecte ci-dessus : il évalue également le code JavaScript qui lui est passé dans la portée globale sans lire ni modifier les liaisons locales, ce qui permet aux moteurs d'effectuer plus d'optimisations que l'évaluation directe avec eval().
La différence entre eval() et Function() réside dans le fait que la chaîne de caractères source transmise à Function() est analysée comme un corps de fonction, et non comme un script. Il existe quelques nuances — par exemple, vous pouvez utiliser des instructions return au niveau supérieur d'un corps de fonction, mais pas dans un script.
Le constructeur Function() est utile si vous souhaitez créer des liaisons locales dans votre source évaluée, en passant les variables comme paramètres.
Les fonctions eval() et Function() évaluent implicitement du code arbitraire et sont interdites dans les paramètres stricts CSP. Il existe également des alternatives plus sûres (et plus rapides !) à eval() ou Function() pour les cas d'utilisation courants.
Vous ne devez pas utiliser eval() pour accéder dynamiquement aux propriétés. Prenons l'exemple suivant, où la propriété de l'objet à laquelle il faut accéder n'est connue qu'au moment où le code est exécuté. Cela peut être fait avec eval() :
Cependant, eval() n'est pas nécessaire ici — en fait, il est plus sujet aux erreurs, car si propName n'est pas un identifiant valide, cela entraîne une erreur de syntaxe. De plus, si getPropName n'est pas une fonction que vous contrôlez, cela peut entraîner l'exécution de code arbitraire. À la place, utilisez les accesseurs de propriétés, qui sont beaucoup plus rapides et sûrs :
Vous pouvez même utiliser cette méthode pour accéder aux propriétés descendantes. Avec eval(), cela ressemblerait à ceci :
Éviter eval() ici peut être fait en divisant le chemin de la propriété et en parcourant les différentes propriétés :
Définir une propriété de cette manière fonctionne de manière similaire :
Cependant, sachez que l'utilisation d'accesseurs entre crochets avec une entrée non contrainte n'est pas non plus sûre : cela peut entraîner des attaques par injection d'objet (angl.).
JavaScript dispose de fonctions de première classe, ce qui signifie que vous pouvez passer des fonctions en tant qu'arguments à d'autres API, les stocker dans des variables et des propriétés d'objets, etc. De nombreuses API DOM sont conçues dans cette optique, vous pouvez (et devriez) donc écrire :
Les closures sont également utiles pour créer des fonctions paramétrées sans concaténer des chaînes de caractères.
Si la chaîne de caractères sur laquelle vous appelez eval() contient des données (par exemple, un tableau : "[1, 2, 3]"), par opposition à du code, vous devriez envisager de passer à JSON, qui permet à la chaîne de caractères d'utiliser un sous-ensemble de la syntaxe JavaScript pour représenter les données.
Notez que, la syntaxe JSON étant plus limitée que celle de JavaScript, de nombreux littéraux JavaScript valides ne seront pas analysés en tant que JSON. Par exemple, les virgules finales ne sont pas autorisées en JSON, et les noms de propriétés (clés) dans les littéraux d'objet doivent être placés entre guillemets. Veillez à utiliser un sérialiseur JSON pour générer des chaînes de caractères qui seront ensuite analysées en tant que JSON.
Il est généralement préférable de transmettre des données soigneusement contrôlées plutôt que du code arbitraire. Par exemple, une extension conçue pour extraire le contenu de pages Web pourrait définir ses règles d'extraction dans XPath plutôt que dans du code JavaScript.
Cette méthode peut être utilisée pour exécuter une entrée arbitraire avec les privilèges de l'appelant. Si l'entrée est une chaîne de caractères potentiellement dangereuse fournie par un·e utilisateur·ice, cela constitue un vecteur possible pour des attaques de par script inter-site (XSS).
Par exemple, le code suivant montre comment eval() pourrait exécuter codeMailveillant fourni par un·e utilisateur·ice :
Les sites web dotés d'une politique de sécurité du contenu (CSP) qui définissent script-src ou default-src empêcheront l'exécution de ce code par défaut. Si vous devez autoriser l'exécution des scripts via eval(), vous pouvez atténuer les risques en affectant toujours une instance de TrustedScript au lieu d'une chaîne de caractères, et en imposant les types de confiance à l'aide de la directive CSP require-trusted-types-for. Cela garantit que l'entrée est passée par une fonction de transformation.
Pour permettre l'exécution de eval(), vous devez également définir le mot-clé trusted-types-eval dans votre directive CSP script-src. Le mot-clé unsafe-eval permet également eval(), mais est beaucoup moins sûr que trusted-types-eval car il permettrait l'exécution même sur les navigateurs qui ne prennent pas en charge les types de confiance.
Par exemple, la CSP requise pour votre site pourrait ressembler à ceci :
Le comportement de la fonction de transformation implémentée dans votre politique de types de confiance dépend du cas d'utilisation spécifique qui nécessite un script fourni par l'utilisateur·ice. Si possible, vous devez verrouiller les scripts autorisés sur le code exact que vous acceptez d'exécuter. Si cela n'est pas possible, vous pouvez autoriser ou bloquer l'utilisation de certaines fonctions dans l'entrée fournie.
Notez que le premier exemple montre comment utiliser la méthode avec les types de confiance. Les autres exemples omettent cette étape pour plus de concision.
Pour atténuer le risque de XSS, il faut toujours affecter des instances de TrustedScript au paramètre script. Il faut également le faire si vous imposez les types de confiance pour d'autres raisons et souhaitez autoriser certaines sources de scripts permises (par CSP: script-src).
Les types de confiance ne sont pas encore pris en charge sur tous les navigateurs, donc nous définissons d'abord le prothèse minimale de Trusted Types. Cela agit comme un remplacement transparent pour l'API JavaScript Trusted Types :
Ensuite, nous créons un TrustedTypePolicy qui définit une méthode createScript() pour transformer des chaînes de caractères en instances de TrustedScript.
Dans cet exemple, nous supposons que vous disposez d'une fonction transformedScript() qui définit votre logique de transformation/filtrage.
Ensuite, nous utilisons l'objet policy pour créer un objet TrustedScript à partir d'une chaîne de caractères potentiellement non sûre :
L'objet TrustedScript peut maintenant être transmis à eval() :
Dans le code suivant, les deux instructions contenant eval() retournent 42. La première évalue la chaîne de caractères "x + y + 1" ; la seconde évalue la chaîne de caractères "42".
eval() retourne la valeur de complétion des instructions. Pour if, ce serait la dernière expression ou instruction évaluée.
L'exemple suivant utilise eval() pour évaluer la chaîne de caractères str. Cette chaîne de caractères consiste en des instructions JavaScript qui affectent à z la valeur de 42 si x vaut cinq, et 0 sinon. Lorsque la seconde instruction est exécutée, eval() entraînera l'exécution des instructions, les instructions seront évaluées et la valeur de z sera donc retournée, car la valeur de complétion d'une affectation est la valeur affectée.
Si vous affectez plusieurs valeurs, la dernière valeur est retournée.
| ECMAScript® 2027 Language Specification # sec-eval-x |
Activez JavaScript pour afficher ce tableau de compatibilité des navigateurs.
Cette page a été modifiée le 21 févr. 2026 par les contributeur·ice·s du MDN.
Votre modèle pour un internet meilleur.
Visitez la société mère à but non lucratif de Mozilla Corporation, la Fondation Mozilla.
Certaines parties de ce contenu sont protégées par le droit d'auteur ©1998—2026 des contributeurs individuels de mozilla.org. Contenu disponible sous une licence Creative Commons.