call et apply en JavaScript : les erreurs les plus courantes et comment les éviter

Formateur Python en ligne pour débutants

Apprenez Python facilement sans surcharge théorique. Résolvez des tâches pratiques avec vérification automatique et écrivez du code directement dans le navigateur.

Start Course

call et apply en JavaScript : Les erreurs les plus courantes et comment les éviter



Avez-vous déjà regardé du code JavaScript écrit par quelqu'un d'autre et vu des constructions étranges comme func.call(this, arg1, arg2) ou func.apply(this, [arg1, arg2]) ? Et vous êtes-vous demandé : "Mais quelle est la différence, en fait ?" Si oui, vous n'êtes pas seul. La question "What is the difference between call and apply?" est l'une des plus populaires sur Stack Overflow avec des centaines de milliers de vues. Et ce n'est pas un hasard.



La confusion entre call et apply est un piège classique pour les débutants (et pas seulement). Dans cet article, nous ne nous contenterons pas de vous expliquer la théorie. Nous allons analyser le top 5 des erreurs réelles, montrer comment les corriger, et vous donner un algorithme clair qui vous débarrassera définitivement de la confusion. C'est parti !



Petit rappel : que sont call et apply ?



Avant de plonger dans les erreurs, rafraîchissons-nous la mémoire. Les méthodes call et apply sont des méthodes intégrées aux fonctions en JavaScript. Leur objectif principal est de spécifier explicitement le contexte d'appel (this) pour une fonction. En d'autres termes, elles permettent de dire : "Hé, fonction, imagine que tu travailles avec cet objet".



Syntaxe :



func.call(context, arg1, arg2, ...);func.apply(context, [arg1, arg2, ...]);


La différence clé :

  • call prend les arguments séparés par des virgules (une liste).
  • apply prend les arguments sous forme de tableau (ou d'un objet semblable à un tableau).


Voilà. C'est la seule différence. Mais c'est précisément à cause de ce "détail" que surviennent la plupart des erreurs. Analysons-les.



Top 5 des erreurs lors de l'utilisation de call et apply



Erreur n°1 : Confusion avec la liste des arguments (la plus fréquente !)



C'est le "roi" de toutes les erreurs. Vous avez écrit une fonction qui attend des arguments un par un, mais vous avez passé un tableau via call. Ou l'inverse.



Exemple catastrophe :



function greet(greeting, punctuation) {    console.log(greeting + ', ' + this.name + punctuation);}

const user = { name: 'Anna' };

// Erreur : on passe un tableau, mais on utilise callgreet.call(user, ['Bonjour', '!']); // Résultat : "Bonjour,! Anna,undefined" — n'importe quoi !


Pourquoi cela ? call attend les arguments un par un. Il a reçu un seul argument — un tableau entier — et l'a placé dans la variable greeting. punctuation est restée undefined.



Comment corriger ? Utilisez apply si les données sont déjà dans un tableau :



greet.apply(user, ['Bonjour', '!']); // Résultat : "Bonjour, Anna!" — correct !


Ou dépliez le tableau avec l'opérateur spread (approche moderne) :



greet.call(user, ...['Bonjour', '!']); // Cela fonctionne aussi !


Erreur n°2 : Oublier que apply fonctionne avec des objets semblables à des tableaux



Beaucoup pensent que apply n'accepte que un vrai tableau. En réalité, il accepte tout objet semblable à un tableau (array-like object) : il doit avoir une propriété length et des clés numériques.



Exemple :



function sum() {    let total = 0;    for (let i = 0; i < arguments.length; i++) {        total += arguments[i];    }    return total;}

// On passe non pas un tableau, mais un objet avec lengthconst args = { 0: 5, 1: 10, 2: 15, length: 3 };

console.log(sum.apply(null, args)); // Résultat : 30 — ça marche !


Mais attention : si l'objet n'a pas de propriété length, apply l'ignorera tout simplement. C'est une erreur fréquente lors du travail avec arguments (objet obsolète) ou avec NodeList.



Erreur n°3 : Utiliser call/apply là où un simple appel suffit



Parfois, les débutants abusent de l'utilisation de ces méthodes. Si vous n'avez pas besoin de changer le contexte (this), un appel de fonction normal est plus simple et plus lisible.



Exemple inutile :



function sayHello() {    console.log('Bonjour !');}

// InutilesayHello.call(null); // MieuxsayHello();


Utilisez call et apply uniquement lorsque vous devez explicitement définir le contexte (this).



Erreur n°4 : Oublier que call et apply exécutent la fonction immédiatement



Contrairement à bind, qui crée une nouvelle fonction avec un contexte lié, call et apply exécutent la fonction immédiatement. Cette confusion conduit souvent à des bugs.



Exemple :



const user = { name: 'Pierre' };function showName() {    console.log(this.name);}

// Erreur : on veut lier le contexte pour une utilisation ultérieureconst boundShow = showName.call(user); // Exécute immédiatement : affiche "Pierre"// boundShow n'est pas une fonction, mais undefined !

// Correct : utiliser bindconst boundShowCorrect = showName.bind(user);boundShowCorrect(); // Affiche "Pierre"


Erreur n°5 : Mauvaise gestion de null et undefined comme contexte



En mode non strict, passer null ou undefined comme contexte fait que this pointe vers l'objet global (window dans le navigateur, global dans Node.js). En mode strict, this reste null ou undefined, ce qui peut provoquer des erreurs.



Exemple :



'use strict';function showGlobal() {    console.log(this);}

showGlobal.call(null); // Affiche : null// En mode non strict, cela afficherait l'objet global


Conseil : Soyez explicite. Si vous n'avez pas besoin d'un contexte spécifique, passez un objet vide {} ou utilisez null uniquement si vous êtes sûr du comportement.



Quand utiliser call vs apply ? Un guide simple



Voici un algorithme simple pour vous aider à choisir :



  1. Les arguments sont-ils déjà dans un tableau ou un objet semblable à un tableau ?
    • Oui → utilisez apply
    • Non → passez à l'étape 2
  2. Connaissez-vous le nombre exact d'arguments ?
    • Oui → utilisez call (plus lisible)
    • Non → utilisez apply avec un tableau dynamique
  3. Utilisez-vous du code moderne (ES6+) ?
    • Utilisez l'opérateur spread avec call pour plus de flexibilité : func.call(context, ...args)


Conclusion



La différence entre call et apply est simple : la façon de passer les arguments. Mais cette simplicité cache de nombreux pièges. N'oubliez pas :



  • call — une liste d'arguments séparés par des virgules
  • apply — un tableau (ou un objet semblable à un tableau)
  • Les deux exécutent la fonction immédiatement
  • Utilisez bind si vous avez besoin de reporter l'exécution


Maîtrisez ces méthodes, et le contexte this n'aura plus de secrets pour vous ! Bon code !

Blogs

Book Recommendations