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 a sept types primitifs et un type objet. C'est peu. Mais le langage convertit implicitement les valeurs d'un type à l'autre dans de nombreuses situations, et c'est la source de la plupart des comportements « bizarres » qu'on lui reproche. Comprendre la coercition, c'est désamorcer ces pièges une fois pour toutes.
const pi = 3.14159 // pas de réassignation
let compteur = 0 // réassignable
compteur = 1
var ancien = 'à éviter' // portée fonction, hoisting, redéclarableRègle simple : const par défaut, let quand la valeur doit changer, var jamais.
const empêche la réassignation, pas la mutation :
const user = { nom: 'Ada' }
user.nom = 'Grace' // autorisé
user = {} // TypeError: Assignment to constant variablelet et const sont hoistées mais inaccessibles avant leur déclaration :
console.log(a) // undefined — var est initialisée à undefined
var a = 1
console.log(b) // ReferenceError: Cannot access 'b' before initialization
let b = 2| Type | Exemples | typeof |
|---|---|---|
number | 42, 3.14, NaN, Infinity | 'number' |
bigint | 9007199254740993n | 'bigint' |
string | 'a', "b", `c` | 'string' |
boolean | true, false | 'boolean' |
undefined | undefined | 'undefined' |
null | null | 'object' (bug historique) |
symbol | Symbol('id') | 'symbol' |
Tout le reste est object : tableaux, fonctions (typeof renvoie 'function'), dates, Map, etc.
Les primitifs sont immuables et comparés par valeur. Les objets sont comparés par référence :
'abc' === 'abc' // true
[1, 2] === [1, 2] // false — deux tableaux distinctsUn seul type number, flottant 64 bits IEEE 754.
0.1 + 0.2 // 0.30000000000000004
0.1 + 0.2 === 0.3 // false
Number.MAX_SAFE_INTEGER // 9007199254740991
2 ** 53 + 1 // 9007199254740992 — précision perdue
2n ** 53n + 1n // 9007199254740993n — BigInt exact
10 / 3 // 3.3333333333333335
Math.trunc(10 / 3) // 3
10 % 3 // 1
(1234.5678).toFixed(2) // '1234.57' (une string)NaN (Not a Number) est la seule valeur différente d'elle-même :
NaN === NaN // false
Number.isNaN(NaN) // true
Number.isNaN('abc') // false
isNaN('abc') // true — l'ancienne fonction convertit d'abordPour de l'argent, travaillez en centimes entiers ou utilisez une bibliothèque décimale.
const nom = 'Ada'
const msg = `Bonjour ${nom}, ${2 + 3} messages`
nom.length // 3
nom[0] // 'A'
nom.at(-1) // 'a'
nom.slice(0, 2) // 'Ad'
' x '.trim() // 'x'
'a,b,c'.split(',') // ['a', 'b', 'c']
'abc'.includes('b') // true
'abc'.padStart(5, '*') // '**abc'
'ha'.repeat(3) // 'hahaha'
'a-b-c'.replaceAll('-', '/')Les chaînes sont en UTF-16. Un emoji compte souvent pour 2 :
'😀'.length // 2
[...'😀'].length // 1 — l'itération respecte les code pointsundefined : valeur non assignée (variable déclarée sans valeur, propriété absente, fonction sans return)null : absence volontaire de valeurlet x
x // undefined
({}).absent // undefined
null == undefined // true
null === undefined // falseOpérateurs modernes pour les gérer :
const port = config.port ?? 3000 // seulement si null/undefined
const ville = user?.adresse?.ville // undefined au lieu d'une erreur
user.prefs ??= {} // assigne si null/undefinedDifférence critique entre ?? et || :
0 || 10 // 10 — 0 est falsy
0 ?? 10 // 0
'' || 'x' // 'x'
'' ?? 'x' // ''Valeurs falsy : false, 0, -0, 0n, '', null, undefined, NaN. Tout le reste est truthy, y compris [], {} et '0'.
if ([]) console.log('un tableau vide est truthy')=== compare sans conversion. == convertit d'abord les opérandes selon un algorithme complexe :
1 == '1' // true
0 == '' // true
0 == '0' // true
'' == '0' // false — pas transitif !
null == 0 // false
[] == false // trueRègle : utilisez toujours === et !==. Seule exception tolérée : x == null, qui teste null et undefined d'un coup.
La coercition apparaît aussi avec + :
1 + '2' // '12' — si un opérande est string, concaténation
'3' * '4' // 12 — les autres opérateurs convertissent en nombre
[] + {} // '[object Object]'Number('42') // 42
Number('42px') // NaN
parseInt('42px', 10) // 42
parseFloat('3.5kg') // 3.5
String(42) // '42'
Boolean('false') // true — chaîne non vide
!!0 // falsePréférez toujours la conversion explicite. Le code devient lisible et les erreurs apparaissent là où elles naissent. Beaucoup de bugs de ce type sont recensés dans les erreurs JavaScript les plus fréquentes.
Écrire une fonction qui transforme une saisie utilisateur en nombre, ou renvoie null si ce n'est pas un nombre valide.
function versNombre(saisie) {
if (typeof saisie !== 'string' || saisie.trim() === '') return null
const n = Number(saisie.replace(',', '.'))
return Number.isFinite(n) ? n : null
}
versNombre('3,5') // 3.5
versNombre('') // null — Number('') vaudrait 0
versNombre('12abc') // nullconst, ===, ?? et les conversions explicites éliminent déjà la majorité des pièges historiques de JavaScript. Le reste du cours s'appuie sur ces réflexes.