Quand vous écrivez un gestionnaire d’événement sur un formulaire HTML, deux syntaxes reviennent sans cesse pour accéder aux champs : this.form dans un handler d’input et document.forms appelé depuis n’importe où dans le script. Les deux renvoient un objet formulaire, mais ils ne fonctionnent pas de la même façon, ni dans le même contexte.
Comprendre leur différence évite des bugs discrets, surtout quand une page contient plusieurs formulaires ou quand le code JavaScript est découplé du HTML.
A lire également : HTML 6.0 : guide pour comprendre les améliorations proposées
Ce que désigne this dans un handler de formulaire HTML
Imaginons un champ input avec un attribut onchange directement dans le HTML. À l’intérieur de ce handler, this représente l’élément qui a déclenché l’événement, c’est-à-dire le champ lui-même.
Pour remonter au formulaire parent, on écrit this.form. Le navigateur renvoie alors l’élément <form> qui contient ce champ. Pas besoin de connaître l’identifiant du formulaire ni sa position dans la page.
A lire aussi : Recherche d'image inversée : trouver les réseaux sociaux d'une personne avec une photo étape par étape
Exemple concret : un select déclenche un calcul quand l’utilisateur change de valeur.
<select name="quantite" onchange="calcul(this.form)">
Dans la fonction calcul, le paramètre reçu est directement le formulaire. On accède ensuite aux autres champs par leur attribut name : form.elements["prix"], form.elements["quantite"].
this.form ne fonctionne que depuis un élément enfant du formulaire. Si le script tourne en dehors d’un handler inline, ou si l’élément n’appartient à aucun <form>, la propriété renvoie null.

document.forms : une collection vivante de tous les formulaires
L’objet document.forms est une HTMLCollection. Il regroupe tous les éléments <form> présents dans le document au moment où vous y accédez.
Vous pouvez cibler un formulaire de trois façons :
- Par son indice dans la page :
document.forms[0]renvoie le premier formulaire rencontré dans le body - Par son attribut
name:document.forms["inscription"]si le formulaire portename="inscription" - Par son attribut
id:document.forms["formContact"]fonctionne aussi avec l’id
Le terme « collection vivante » a une conséquence directe. Si un script ajoute ou retire un formulaire du DOM après le chargement de la page, document.forms reflète le changement en temps réel. Pas besoin de relancer une requête.
Cette approche est utile quand le code JavaScript est séparé du HTML. Un module externe peut accéder à n’importe quel formulaire sans dépendre d’un événement sur un champ précis.
Portée et contexte d’exécution : la vraie ligne de partage
La différence fondamentale tient au contexte d’exécution.
this.form est contextuel. Sa valeur dépend de l’élément sur lequel le handler est attaché. Déplacez le champ dans un autre formulaire, et this.form pointe automatiquement vers le nouveau parent. Le code reste valide sans modification.
document.forms est global. Il part du document et descend vers un formulaire identifié par son nom ou sa position. Le lien est explicite : vous codez en dur le nom ou l’index.
Voici les conséquences pratiques :
- Dans une page avec un seul formulaire, les deux approches se valent.
document.forms[0]etthis.formrenvoient le même objet - Avec plusieurs formulaires,
this.formcible toujours le bon parent sans ambiguïté, tandis quedocument.formsexige de connaître le nom ou la position du formulaire visé - Dans un gestionnaire ajouté via
addEventListener,thispeut ne pas pointer vers l’élément attendu si une arrow function est utilisée. event.currentTarget est alors plus fiable que this
Le piège classique des arrow functions
Avec addEventListener, une fonction classique reçoit this comme référence à l’élément cible. Une arrow function, elle, hérite du this de son contexte lexical, souvent window.
Si vous écrivez input.addEventListener('change', () => { console.log(this.form); }), le résultat sera probablement undefined. Le correctif : utiliser le paramètre event et appeler event.currentTarget.form.
Ce piège n’existe pas avec document.forms, qui ne dépend d’aucun contexte local.

Quand choisir this.form ou document.forms dans un projet
Le choix dépend de l’architecture du code, pas d’une préférence de style.
Pour un handler inline ou un petit script embarqué dans le HTML, this.form reste la voie la plus directe. Le code est court, lisible, et ne casse pas si le formulaire change de nom.
Pour un fichier JavaScript externe qui manipule plusieurs formulaires, document.forms avec un attribut name explicite offre un accès centralisé. Le script n’a pas besoin de savoir quel élément a déclenché l’appel.
Dans les frameworks modernes (React, Vue, Angular), aucune des deux approches n’est courante. Les références au DOM passent par des mécanismes internes (refs, template refs). Mais dès que vous travaillez en JavaScript natif sur du HTML classique, le choix entre this.form et document.forms se pose à chaque formulaire.
Tableau récapitulatif
| Critère | this.form | document.forms |
|---|---|---|
| Portée | Locale (depuis un champ du formulaire) | Globale (depuis n’importe quel script) |
| Type de retour | Un seul HTMLFormElement ou null | HTMLCollection (tous les formulaires) |
| Mise à jour dynamique | Suit le parent DOM actuel | Collection vivante, reflète les ajouts/suppressions |
| Risque avec arrow functions | Oui (this peut être window) | Aucun |
| Dépendance au name/id | Non | Oui (sauf accès par index) |
Pour du code maintenable en JavaScript vanilla, combiner document.forms pour cibler le formulaire et la propriété elements pour atteindre les champs reste une approche solide. Réservez this.form aux cas où le handler est directement lié à un champ du formulaire et où la concision prime. Le bon réflexe, dans tous les cas, est de vérifier que le contexte de this correspond bien à ce que vous attendez avant de remonter vers le formulaire parent.

