iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
iducationducation
IndexArticlesFormationsProfilOutilsBibliothech
N°014 — 2026
Navigation
01Index02Articles03Formations04Profil05Outils06Bibliothech
N°014 — 2026
Formations
JavaScript · Débutant

JavaScript

Apprendre JavaScript de zéro jusqu'au niveau expert : syntaxe moderne, DOM, asynchrone et event loop, modules, prototypes, métaprogrammation, performance et mémoire.

JavaScript ES2025Node.jsDOMVitestVite
01Introduction et environnement02Variables, types et coercition03Conditions et boucles04Fonctions, portée et closures05Objets, tableaux, Map et Set06Le DOM et les événements07Asynchrone : callbacks, promesses, async/await et event loop08Modules, npm, outillage et tests09Prototypes, classes et this10Itérateurs, générateurs, Symbol, Proxy et métaprogrammation11Niveau expert : moteur, performance, mémoire et architecture
Chapitre 5·45 min

Objets, tableaux, Map et Set

Les données réelles arrivent presque toujours sous forme de tableaux d'objets : une réponse d'API, une liste de produits, des lignes de CSV. Savoir les transformer en quelques lignes lisibles est la compétence la plus utilisée au quotidien.

Objets

const nom = 'Ada'
const user = {
  nom,                          // raccourci pour nom: nom
  age: 36,
  'clé avec espace': true,
  ['role_' + 1]: 'admin',       // clé calculée
  saluer() {                    // méthode
    return `Je suis ${this.nom}`
  },
}
 
user.age                        // 36
user['clé avec espace']         // true
user.email                      // undefined
delete user.age
'nom' in user                   // true
Object.hasOwn(user, 'nom')      // true

Déstructuration

const { nom, age = 0, adresse: { ville } = {} } = user
 
const [premier, , troisieme, ...reste] = [10, 20, 30, 40, 50]
 
function afficher({ nom, email = 'n/a' }) {
  console.log(nom, email)
}

Spread et copie

const defaults = { theme: 'clair', langue: 'fr' }
const prefs = { ...defaults, theme: 'sombre' }   // { theme: 'sombre', langue: 'fr' }

Le spread fait une copie superficielle. Pour une copie profonde, structuredClone :

const original = { tags: ['a'], date: new Date() }
const copie = structuredClone(original)
copie.tags.push('b')
original.tags   // ['a']

Parcourir un objet

Object.keys(prefs)      // ['theme', 'langue']
Object.values(prefs)    // ['sombre', 'fr']
Object.entries(prefs)   // [['theme', 'sombre'], ['langue', 'fr']]
 
// Transformer un objet
const enMajuscules = Object.fromEntries(
  Object.entries(prefs).map(([k, v]) => [k, v.toUpperCase()])
)

Immutabilité

const CONFIG = Object.freeze({ api: 'https://api.exemple.fr' })
CONFIG.api = 'autre'    // ignoré (TypeError en mode strict)

Object.freeze est superficiel : les objets imbriqués restent modifiables.

Tableaux

const nums = [5, 3, 8]
nums.push(1)            // ajoute à la fin
nums.pop()              // retire à la fin
nums.unshift(0)         // ajoute au début
nums.shift()            // retire au début
nums.includes(3)        // true
nums.indexOf(8)         // 2
nums.at(-1)             // 8
nums.slice(0, 2)        // [5, 3] — copie
nums.splice(1, 1)       // retire 1 élément à l'index 1 — MUTE le tableau
Array.from({ length: 3 }, (_, i) => i * 2)   // [0, 2, 4]

Méthodes mutantes contre non mutantes

C'est la source d'une quantité énorme de bugs, en particulier avec React où l'état ne doit jamais être muté.

Mute le tableauRenvoie une copie (ES2023+)
sort()toSorted()
reverse()toReversed()
splice()toSpliced()
arr[i] = xwith(i, x)
const notes = [12, 8, 15]
const triees = notes.toSorted((a, b) => a - b)   // [8, 12, 15], notes intact

sort() sans comparateur trie en ordre lexicographique : [10, 9, 1].sort() donne [1, 10, 9]. Passez toujours une fonction de comparaison pour des nombres.

Les méthodes fonctionnelles

const commandes = [
  { id: 1, client: 'Ada', total: 120, statut: 'payee' },
  { id: 2, client: 'Linus', total: 45, statut: 'annulee' },
  { id: 3, client: 'Ada', total: 80, statut: 'payee' },
  { id: 4, client: 'Grace', total: 200, statut: 'payee' },
]
 
commandes.map(c => c.total)                          // [120, 45, 80, 200]
commandes.filter(c => c.statut === 'payee')          // 3 commandes
commandes.find(c => c.client === 'Grace')            // { id: 4, ... }
commandes.findLast(c => c.client === 'Ada')          // { id: 3, ... }
commandes.some(c => c.total > 150)                   // true
commandes.every(c => c.total > 10)                   // true
commandes.reduce((s, c) => s + c.total, 0)           // 445
commandes.flatMap(c => [c.id, c.total])              // [1, 120, 2, 45, ...]

Regrouper, avec Object.groupBy (ES2024) :

const parClient = Object.groupBy(commandes, c => c.client)
// { Ada: [...2 commandes], Linus: [...], Grace: [...] }
 
const caParClient = Object.fromEntries(
  Object.entries(parClient).map(([client, cmds]) => [
    client,
    cmds.reduce((s, c) => s + c.total, 0),
  ])
)
// { Ada: 200, Linus: 45, Grace: 200 }

Map

Map est un dictionnaire dont les clés peuvent être de n'importe quel type, qui garde l'ordre d'insertion et expose sa taille.

const visites = new Map()
visites.set('/accueil', 10)
visites.set('/blog', 3)
visites.get('/blog')            // 3
visites.has('/contact')         // false
visites.size                    // 2
visites.delete('/blog')
 
const elementsVus = new Map()
elementsVus.set(document.body, Date.now())   // un objet comme clé

Quand utiliser Map plutôt qu'un objet ? Dès que les clés sont dynamiques (issues de données utilisateur) ou non-string, ou quand on ajoute et supprime souvent. Un objet peut entrer en collision avec des clés comme __proto__ ou constructor.

Set

const tags = new Set(['js', 'web', 'js'])
tags.size               // 2
tags.add('node')
tags.has('web')         // true
 
const uniques = [...new Set([1, 2, 2, 3])]   // [1, 2, 3]

Opérations ensemblistes natives (ES2025) :

const a = new Set([1, 2, 3])
const b = new Set([2, 3, 4])
a.union(b)              // Set {1, 2, 3, 4}
a.intersection(b)       // Set {2, 3}
a.difference(b)         // Set {1}
a.isSubsetOf(b)         // false

JSON

const json = JSON.stringify({ nom: 'Ada', date: new Date(0) }, null, 2)
const obj = JSON.parse(json)
obj.date                // '1970-01-01T00:00:00.000Z' — une string, plus une Date

JSON.stringify ignore les fonctions, undefined et les Symbol, et convertit les dates en chaînes. Map et Set deviennent {}. C'est pour cela qu'on préfère structuredClone à JSON.parse(JSON.stringify(x)) pour cloner.

Exercice : tableau de bord de ventes

À partir du tableau commandes ci-dessus, calculer pour les commandes payées : le chiffre d'affaires total, le panier moyen, et le meilleur client.

const payees = commandes.filter(c => c.statut === 'payee')
const ca = payees.reduce((s, c) => s + c.total, 0)
const panierMoyen = ca / payees.length
 
const parClient = new Map()
for (const { client, total } of payees) {
  parClient.set(client, (parClient.get(client) ?? 0) + total)
}
const [meilleur] = [...parClient].toSorted((a, b) => b[1] - a[1])
 
console.log({ ca, panierMoyen, meilleur })
// { ca: 400, panierMoyen: 133.33333333333334, meilleur: ['Ada', 200] }

Map pour les dictionnaires dynamiques, Set pour l'unicité, méthodes non mutantes pour les transformations. Avec map, filter et reduce bien en main, la plupart des traitements de données tiennent en une chaîne de trois lignes.

Précédent
Fonctions, portée et closures
Suivant
Le DOM et les événements

Développeur fullstack passionné. J'apprends en construisant et je documente tout — front, back, outils. Le code s'apprend mieux en public.

Naviguer

IndexTous les articlesFormationsProfilOutilsBibliothech

Ailleurs

GitHub RSS

Newsletter

Les articles, libs et découvertes. Une fois par semaine, pas plus.

© 2026 William LoreeConçu & codé à la main