Jquery
Junior
Quiz-Jquery-Junior
Jquery-Ajax
Deferred-Promise
Delegation-Evenements
Jquery-Plugins
Questions-Entretien-Jquery-Junior
Qcm-Jquery-Junior
Performance-Jquery
Javascript
Front-End
Ajax-Api
Legacy-Frontend
📝
Entretien jQuery Junior : AJAX, plugins et perf
20 questions jQuery niveau junior : requêtes AJAX ($.ajax, $.get, $.post), déféré (Deferred/Promise), délégation d'événements, création de plugins et bonnes pratiques de performance. Pour un entretien jQuery Junior.
Banque de révision : les 60 questions corrigées
Voici l'intégralité des 60 questions de « Entretien jQuery Junior : AJAX, plugins et perf », chacune avec sa bonne réponse et son explication. Le quiz interactif ci-dessus en tire une sélection aléatoire à chaque tentative — utilisez cette liste complète pour réviser.
Explication :
$.get(url, data, success, dataType) est un raccourci de $.ajax() avec method: 'GET' préconfiguré. $.ajax() est l'API complète qui expose tous les paramètres : headers, beforeSend, timeout, xhrFields, etc. Tous deux retournent un objet jqXHR (Deferred).
En entretien : utilise
$.get() / $.post() pour les cas simples, $.ajax() dès que tu as besoin de headers, timeout ou gestion fine des erreurs.
Explication :
$.ajax() retourne un jqXHR qui implémente l'interface Deferred. On chaîne .done(fn) pour le succès, .fail(fn) pour l'erreur, et .always(fn) pour le code exécuté dans les deux cas. Les méthodes .success() et .error() sont dépréciées depuis jQuery 1.8.
Explication :
$.ajaxSetup({ headers: { 'X-CSRF-Token': token }, timeout: 5000 }) définit des paramètres par défaut appliqués à toutes les requêtes $.ajax() suivantes. Utile pour injecter un header d'authentification partout. Attention : impacte aussi les plugins qui utilisent $.ajax() en interne.
Utilise
$.ajaxSetup() avec parcimonie. Préfère $.ajaxPrefilter() pour des intercepteurs plus ciblés.
Explication :
$.ajax() retourne un objet jqXHR. En appelant jqXHR.abort(), la requête est annulée et le callback .fail() est déclenché avec statusText === 'abort'. Exemple : var req = $.ajax(url); req.abort();. Indispensable pour éviter les race conditions (ex : autocomplete).
Explication :
$.when() accepte plusieurs objets Deferred et résout quand tous sont résolus : $.when($.get('/api/a'), $.get('/api/b')).done(function(resA, resB) {}). Chaque argument du callback correspond aux données d'une requête. Si l'une échoue, .fail() est déclenché immédiatement.
Équivalent jQuery de
Promise.all(). En entretien, montre que tu connais aussi Promise.all() natif — plus moderne pour du nouveau code.
Explication :
$.param() sérialise un objet en chaîne URL-encodée : "name=Alice&age=30". Utile pour construire manuellement le corps d'une requête POST ou les paramètres d'une URL GET. C'est ce que .serialize() utilise en interne pour les formulaires.
Explication :
.serialize() produit "email=a@b.com&password=1234" (chaîne). .serializeArray() produit [{name:'email', value:'a@b.com'}, ...] (tableau). Le tableau est plus pratique pour manipuler les valeurs en JS avant envoi. Ni l'un ni l'autre ne sérialise les <input type="file">.
Pour envoyer des fichiers, utilise
FormData natif avec $.ajax({ data: formData, processData: false, contentType: false }).
Explication :
Le paramètre
headers accepte un objet clé/valeur : $.ajax({ url: '/api', headers: { 'Authorization': 'Bearer ' + token } }). Ces headers sont ajoutés à la requête XHR. Combiné avec $.ajaxSetup(), on peut injecter un token d'auth sur toutes les requêtes.
Explication :
async: false rend la requête synchrone : le navigateur est bloqué jusqu'à la réponse. Déprécié depuis jQuery 1.8. Les navigateurs modernes affichent un avertissement. À remplacer par .done(), .then() ou async/await.
En entretien : expliquer pourquoi
async: false est une mauvaise pratique et proposer l'alternative (Promise, async/await) distingue un vrai junior d'un débutant.
Explication :
Avec
cache: false, jQuery ajoute automatiquement un paramètre _=timestamp à l'URL : /api/data?_=1714500000000. Cela rend chaque URL unique, contournant le cache navigateur. IE était particulièrement agressif dans la mise en cache des GET.
Explication :
Pour envoyer des fichiers, utilise
FormData natif. processData: false empêche jQuery de sérialiser l'objet, et contentType: false laisse le navigateur définir le bon multipart/form-data avec le boundary.
Montre en entretien que tu comprends pourquoi
processData: false et contentType: false sont nécessaires — c'est un détail qui distingue un junior qui comprend de celui qui copie-colle.
Explication :
$.ajax() retourne un jqXHR, un objet jQuery qui enveloppe le XHR natif et implémente l'interface Deferred/Promise de jQuery. Il expose .done(), .fail(), .always(), .then(), .abort(). Ce n'est pas une Promise ES6 standard.
Explication :
beforeSend: function(xhr) {} s'exécute juste avant l'envoi. On peut modifier les headers : xhr.setRequestHeader('X-Token', token), afficher un spinner, ou retourner false pour annuler la requête.
Pattern classique :
beforeSend pour afficher le spinner et ajouter le token CSRF, complete pour masquer le spinner — quelle que soit la réussite ou l'échec.
Explication :
$("#box").load("/page.html") fait une requête GET et injecte automatiquement le HTML retourné dans l'élément. On peut cibler une portion : .load("/page.html #section"). Pratique pour les includes partiels sans rechargement de page.
Explication :
$.getJSON(url, callback) est un raccourci de $.ajax({ url, dataType: 'json', success: callback }). jQuery parse automatiquement la réponse JSON et passe l'objet JS au callback. Retourne un jqXHR, donc chainable avec .done(fn).fail(fn).
Explication :
$.Deferred() crée un objet représentant une opération asynchrone. On appelle .resolve(data) en cas de succès (déclenche .done()) ou .reject(err) en cas d'échec (déclenche .fail()). Exemple : function loadData() { var d = $.Deferred(); setTimeout(() => d.resolve('ok'), 1000); return d.promise(); }.
Connais la différence avec
Promise ES6 : $.Deferred() est mutable (resolve/reject depuis l'extérieur), une Promise ne peut être résolue qu'en interne.
Explication :
.promise() retourne un objet qui expose uniquement .done(), .fail(), .then() — mais pas .resolve() / .reject(). Bonne pratique : toujours retourner deferred.promise() depuis une fonction, jamais le Deferred brut.
Explication :
.done(fn) ajoute un callback et retourne le même Deferred. .then(fnSuccess, fnFail) retourne un nouveau Deferred avec la valeur retournée par le callback, permettant le chaining avec transformation : $.get('/api').then(data => data.users).done(users => render(users)).
Utilise
.then() pour les transformations, .done() pour les effets de bord (affichage, log).
Explication :
.state() retourne "pending" (en attente), "resolved" (succès), ou "rejected" (rejeté). Utile pour tester l'état d'un Deferred dans les tests unitaires ou pour un système de retry.
Explication :
Avant jQuery 3, le Deferred n'était pas conforme Promises/A+ : le
.then() ne propageait pas correctement les exceptions synchrones. jQuery ajoute .done(), .fail(), .always(), absentes des Promises natives. On ne peut pas utiliser async/await directement sur un jqXHR jQuery 1/2.
Réponse experte : convertir avec
Promise.resolve($.ajax(...)) pour utiliser async/await avec jQuery.
Explication :
.always(fn) s'exécute dans tous les cas : résolution ou rejet. Utile pour masquer un loader ou nettoyer des ressources. Si un Deferred échoue, $.when() est rejeté dès ce premier échec.
Explication :
La délégation s'attache sur un parent et filtre par sélecteur enfant :
$('#liste').on('click', '.item', fn). L'événement bubble du .item jusqu'au #liste, où jQuery vérifie si event.target correspond au sélecteur. Fonctionne pour les éléments ajoutés dynamiquement.
Délègue sur l'ancêtre stable le plus proche, jamais sur
document ou body sauf si nécessaire — c'est plus performant.
Explication :
jQuery 1.7 a introduit
.on() qui unifie .bind() (handler direct), .live() (délégation sur document), et .delegate() (délégation sur un parent). .on() est plus flexible, plus performant et couvre tous les cas.
Explication :
Le handler est attaché sur un parent stable dans le DOM. Quand un clic se produit sur un enfant dynamique, l'événement remonte (bubble) jusqu'au parent. jQuery vérifie si
event.target correspond au sélecteur et exécute le handler. L'élément n'a pas besoin d'exister au moment du binding.
Explication :
.one() attache un handler d'événement qui se désabonne automatiquement après sa première exécution. Utile pour les modales, les tutoriels first-run, ou les boutons de confirmation.
Explication :
En délégation :
$('#liste').on('click', '.btn', fn). event.target est l'élément réellement cliqué, event.currentTarget est toujours #liste (l'élément sur lequel .on() est attaché). Dans le handler en délégation, $(this) correspond au .btn qui a matché le sélecteur.
Question fréquente en entretien. Retiens :
$(this) en délégation = l'élément du sélecteur (le .btn), pas le target exact ni le parent.
Explication :
La syntaxe
"event.namespace" groupe des handlers : $(el).on('click.tooltip mouseenter.tooltip', fn). Pour tout supprimer : $(el).off('.tooltip') — supprime tous les handlers du namespace sans affecter les autres. Indispensable dans les plugins.
Explication :
Un plugin jQuery s'ajoute à
$.fn (alias de jQuery.prototype). La méthode doit retourner this.each() pour le chaînage et le support des collections : $.fn.monPlugin = function(options) { return this.each(function() { /* traitement */ }); };.
3 règles essentielles : 1) retourner
this pour le chaînage, 2) this.each() pour les collections, 3) IIFE pour protéger $.
Explication :
L'IIFE sert deux objectifs : 1) Alias sûr — si
$.noConflict() libère $ pour une autre librairie, le plugin continue de fonctionner. 2) Scope privé — les variables internes ne polluent pas le scope global.
Explication :
$.extend({}, defaults, options) crée un nouvel objet en fusionnant les defaults avec les options passées. Le {} en premier évite de muter l'objet defaults. En exposant $.fn.monPlugin.defaults, on permet aux utilisateurs de changer les defaults globalement.
Pattern avancé : expose
$.fn.monPlugin.defaults = { speed: 200 } pour la personnalisation globale sans passer d'options à chaque appel.
Explication :
$(el).data('monPlugin', { initialized: true, options: opts }) stocke des données associées à l'élément dans le cache interne jQuery. On les récupère avec $(el).data('monPlugin'). Les données sont nettoyées automatiquement si l'élément est supprimé via .remove().
Explication :
Pattern de guard : si le plugin a déjà stocké son état via
.data(), retourner this immédiatement. Sinon, initialiser et stocker l'état. Évite les double-bindings d'événements et les initialisations redondantes.
Alternative : expose une méthode
'destroy' qui nettoie .data() et .off('.monPlugin'), permettant une réinitialisation propre.
Explication :
Pattern jQuery courant :
$.fn.monPlugin = function(method, ...args) { if (typeof method === 'string') { /* appel méthode */ } else { /* init */ } }. Usage : $('#el').monPlugin('open'). C'est le pattern utilisé par jQuery UI.
Explication :
Chaque appel
$("#id") déclenche une traversée du DOM. Si le même sélecteur est utilisé dans une boucle ou un handler fréquent, stocker le résultat évite ce coût : var = $('#submit');. Convention : préfixer les variables jQuery avec $.
Règle pratique : si tu utilises un sélecteur plus d'une fois, mets-le en cache. Critique dans les loops, scroll handlers, ou animations.
Explication :
.remove() supprime l'élément du DOM et efface toutes les données .data() et handlers .on(). .detach() retire l'élément mais conserve ces métadonnées. Utile pour déplacer un élément fréquemment sans perdre les handlers.
Explication :
Chaque
.append() dans une boucle déclenche un reflow. Solution : construire une chaîne HTML complète et faire une seule insertion : var html = ''; $.each(data, function(i,d) { html += '<li>' + d + '</li>'; }); $('ul').html(html);.
Alternative moderne :
document.createDocumentFragment() pour construire le DOM hors de la page puis insérer en une fois.
Explication :
stopPropagation() arrête la propagation vers les parents. stopImmediatePropagation() arrête la propagation ET bloque les autres handlers sur le même élément pour le même événement. Si plusieurs handlers .on('click') sont sur #btn, stopImmediatePropagation() dans le premier empêche les suivants.
Explication :
Passer un objet à
.css() applique toutes les propriétés en une opération, minimisant les reflows. Chaque appel individuel peut déclencher un reflow séparé. Mieux encore : utiliser .addClass() avec une classe CSS prédéfinie — meilleur pour la maintenabilité.
Règle d'or : évite le CSS inline via JS. Définis une classe et utilise
.addClass(). Réserve .css() pour les valeurs dynamiques (positions calculées, couleurs générées).
Explication :
$.noop est une fonction vide partagée. Utile comme valeur par défaut de callback : function animate(el, cb) { cb = cb || $.noop; cb(); }. Évite de créer une nouvelle fonction anonyme vide à chaque appel — micro-optimisation et bonne pratique.
Explication :
$.each(array/object, fn) est un itérateur généraliste pour les tableaux et objets JS. $(selector).each(fn) itère sur les éléments DOM de la collection jQuery avec this == l'élément courant.
Dans les plugins, utilise
return this.each(function() {}) pour gérer les collections multi-éléments et maintenir le chaînage.
Explication :
$.grep(array, fn) filtre un tableau en retenant les éléments pour lesquels la fonction retourne true. Seuls 3 et 4 sont > 2. Équivalent de Array.prototype.filter().
Explication :
$.map(array, fn) transforme chaque élément et retourne un nouveau tableau aplati. Différence avec .map() natif : $.map() aplatit les tableaux retournés, et retourner null/undefined supprime l'élément du résultat.
Explication :
$.inArray(value, array) retourne l'index de la première occurrence, ou -1. Attention à l'ordre : valeur d'abord, tableau ensuite. Pour tester la présence : if ($.inArray('alice', users) !== -1) {}.
Piège classique : l'ordre inversé des arguments. Préfère
array.includes(value) en JS moderne — plus lisible et sans dépendance jQuery.
Explication :
Le premier argument
true active la fusion profonde : les objets imbriqués sont fusionnés récursivement. Sans true, c'est une fusion superficielle. Exemple : $.extend(true, {}, {a:{x:1}}, {a:{y:2}}) → {a:{x:1, y:2}}.
Explication :
$(selector, context) limite la recherche à un sous-arbre DOM. Équivalent de $(context).find(selector). Dans les plugins : $('.btn', this) cherche les .btn uniquement à l'intérieur de l'élément courant.
Toujours scoper les sélecteurs dans les plugins pour éviter les collisions avec d'autres composants.
Explication :
$.type() est plus précis que typeof : il retourne "array" pour les tableaux, "null" pour null, "regexp", "date", etc. typeof [] retourne "object" (imprécis).
Explication :
$.merge(first, second) mute le premier tableau en y ajoutant les éléments du second, puis retourne ce tableau. Différence importante avec [...a, ...b] qui crée un nouveau tableau sans mutation.
Explication :
complete: function(xhr, status) {} est exécuté après success ou error, quelle que soit l'issue. Correspond à .always() dans le chaining. Utile pour masquer un spinner ou réactiver un bouton.
Pattern production :
beforeSend → affiche spinner, complete → masque spinner. success → mise à jour UI, error → message d'erreur.
Explication :
timeout: 5000 (ms) annule la requête si elle ne se termine pas dans le délai. Le callback .fail() est appelé avec statusText === 'timeout'. On teste : if (jqXHR.statusText === 'timeout') { /* retry */ }.
Explication :
$.Callbacks(flags) crée une liste de fonctions gérable. Flags : 'once' (s'exécute une seule fois), 'memory' (les callbacks ajoutés après le fire reçoivent les derniers args), 'unique' (pas de doublons), 'stopOnFalse'. C'est la base interne de $.Deferred().
Utile pour implémenter un système d'événements ou un hook system dans une librairie.
Explication :
$.trim(str) supprime les espaces en début et fin de chaîne. Équivalent de str.trim() natif. $.trim() était utile pour la compatibilité IE8. En code moderne, préfère le .trim() natif.
Explication :
$.isFunction(fn) est déprécié depuis jQuery 3.3 au profit de typeof fn === 'function'. Les deux sont équivalents pour les fonctions classiques.
Recommandation : utilise
typeof fn === 'function' — plus lisible, pas de dépendance jQuery, ne sera jamais déprécié.
Explication :
typeof [] retourne "object" — comportement historique JS. $.isArray([]) retourne true. Équivalent moderne : Array.isArray([]). $.isArray() est déprécié depuis jQuery 3.2.
Explication :
$(el).trigger('monEvent', [data1, data2]) déclenche l'événement et le propage en bubbling. Le handler reçoit les données en arguments : $(el).on('monEvent', function(e, d1) {}). Pattern PubSub jQuery : $(document) sert de bus d'événements global.
Pattern PubSub :
$(document).on('userLoggedIn', fn) pour s'abonner, $(document).trigger('userLoggedIn', [user]) pour publier.
Explication :
.get(0) et retournent le nœud DOM natif. Utile pour les APIs natives non couvertes par jQuery : var canvas = $('#myCanvas').get(0); var ctx = canvas.getContext('2d');.
Explication :
$(el).queue(fn) ajoute une fonction à la file d'exécution "fx" (la même que .animate()). La fonction reçoit next qu'il faut appeler pour continuer : .fadeIn().queue(function(next) { doSomething(); next(); }).fadeOut();.
Explication :
$.fn.extend(obj) équivaut à $.fn.monPlugin = function() {} mais permet d'ajouter plusieurs méthodes à la fois. Les méthodes s'utilisent sur les collections : $('.el').monPlugin(). Différent de $.extend() qui étend l'objet $ lui-même.
Utilise
$.extend() pour les utilitaires statiques ($.maFn()), $.fn.extend() pour les méthodes d'instance ($(el).maFn()).
Explication :
.triggerHandler() exécute les handlers jQuery sans : 1) bubbling, 2) comportement natif (form non soumis), 3) s'applique uniquement au premier élément. Utile pour les tests ou pour déclencher un hook sans effets de bord.
Explication :
jQuery n'a pas de
$.debounce() natif. Pattern : var timer; $(window).on('resize', function() { clearTimeout(timer); timer = setTimeout(function() { /* action */ }, 300); });. La fonction ne s'exécute qu'après 300ms sans nouvel appel.
En production, utilise Lodash
_.debounce() ou écris ta propre : function debounce(fn, delay) { var t; return function() { clearTimeout(t); t = setTimeout(() => fn.apply(this, arguments), delay); }; }.
Explication :
$.holdReady(true) retarde le DOM ready. Utile pour charger un plugin asynchrone avant de lancer l'application : $.holdReady(true); $.getScript('/plugin.js', function() { $.holdReady(false); });.
Usage rare mais utile pour les architectures modulaires qui chargent des dépendances dynamiquement avant l'init de l'app.