# Premiers pas

# Hello world

console.log('Hello world')

Il y a un grand nombre de notions cachées dans cette simple ligne :

  • console est un objet de l'environnement : il n'est pas défini dans le langage (dans le standard ECMAScript). Il permet d'afficher ce qu'on lui donne en arguments : soit dans la console du navigateur (pour les... navigateurs), soit dans la sortie standard pour node.js
  • log est une propriété de l'objet console
  • log est une fonction
  • En JavaScript, une fonction est un objet, avec un super pouvoir : il est invocable (callable object)
  • log est appelée (on dit aussi invoquée) en tant que méthode sur l'objet console
  • 'Hello world' est un argument passé à la fonction console.log, qui accepte un nombre quasi infini de paramètres
  • console.log est une fonction qui affiche dans la console des "dev tools" (Outils de développement) le contenu des arguments qui lui sont passés : ici, "Hello world" sera affiché dans la console
  • À noter : la syntaxe à point ("dot syntax") qu'on retrouve en java et en python pour accéder à une propriété d'un objet

# Les types en JS

Il y aura 8 types en JavaScript dans la version ES2020

# Les 7 types primitifs

En JavaScript, les valeurs dont les types sont des types primitifs sont immutables : on ne peut pas modifier ces valeurs.

Voici les 7 types primitifs avec des exemples :

  • Undefined (une seule valeur pour ce type : undefined)
  • Null (idem: null)
  • Number (42, 0.42, 1e22, Infinity, NaN)
  • String ('Blimey!', "Ahoy!", `Aye`)
  • Boolean (true, false)
  • Symbol (ES6 - ES2015) (Symbol('Garanti unique'))
  • BigInt (ES2020) (9007199254740991n)

# Le type objet

Tout autre valeur est un objet. Par défaut, un objet est mutable : on peut modifier ses propriétés, en enlever, en ajouter. Voici quelques exemples :

  • Objet ({}, console)
  • Fonction (function () {}, console.log)
  • Tableau (Array) ([], [1, 2, 3])
  • Date (new Date())
  • RegExp (/^debut.*fin$/i)
  • Map (new Map())
  • Set (new Set())
  • ...

# Déclarations de variables

Pour fonctionner, un programme doit garder en mémoire des valeurs : elles sont stockées dans des variables. Il existe 3 façons de déclarer une variable : avec le mot-clé var, et, depuis ES6, avec les mots-clés let et const.

Pour faire simple, on va toujours utiliser var. Si vous voulez vraiment connaître les différences (Sinon, passez à la suite) :

Une variable déclarée avec le mot-clé var aura pour scope la fonction, et sera accessible avant sa déclaration dans le code (mais sa valeur avant initialisation sera forcément la valeur undefined).

Une variable déclarée avec les mots-clés let ou const aura pour scope le bloc d'instruction dans lequel elle est déclarée : un ensemble d'instructions séparées par des accolades { et }. Ces variables ne seront pas accessibles avant leur déclaration, contrairement à celle déclarée avec var.

La différence entre let et const est qu'une variable déclarée avec const ne peut pas être réassignée :

console.log(first) // undefined
var first
console.log(first) // undefined
first = null
console.log(first) // null

console.log(firstBis) // undefined
var firstBis = 'bis'
console.log(firstBis) // 'bis

// Illustration de la TDZ

// console.log(second) // Provoquerait une erreur ReferenceError : on est ici dans la TDZ de second!
let second
console.log(second) // undefined
second = 'two'
console.log(second) // 'two'
second = 2
console.log(second) // 2


// console.log(third) // Provoquerait une erreur ReferenceError : on est ici dans la TDZ de third !
const third = 3
console.log(second) // '3'
third = 4 // TypeError : on ne peut pas réassigner une variable déclarée avec const
third++ // TypeError : l'incrémentation correspond aussi à une réassignation

# Les opérateurs

Pour manipuler les valeurs et les variables, le langage utilise des opérateurs. Un opérateur a au moins un opérande (une valeur sur lequel il fait une opération), souvent 2, et rarement 3.

# Opérateurs unaires

Un opérateur unaire, comme son nom l'indique, a un seul opérande, exemples :

  • typeof,
  • !,
  • ++,
  • --
// Extrait de code "o1"
typeof undefined // "undefined"
typeof true // "boolean"
typeof 'hello' // "string"
typeof 42 // "number"
typeof Symbol('un symbol') // "symbol"
typeof 3493029430349380n // "bigint"
typeof {} // "object"

typeof null // "object" Bug de ES1 qui ne sera jamais corrigé
typeof function () {} // "function" Une fonction est un objet avec un super pouvoir :
                     // il est invocable avec les parenthèses () : 'callable object' dans la spec,
                     // mais reste un objet : on peut lui ajouter, modifier, supprimer des propriétés

# Falsy values

JavaScript connait aujourd’hui 9 valeurs qui donneront false si elles sont converties en Boolean :

null
undefined
NaN
0
-0
0n
-0n
''
false

Toutes les autres valeurs vaudront true si elles sont converties en Boolean.

Par conséquent :

Boolean({}) // true: Objet vide ne fait pas partie des valeurs falsy
Boolean([]) // true : Array vide ne fait pas partie des valeurs falsy
Boolean(typeof whatever) // vaudra forcément true,
// puisque typeof whatever retourne une chaîne qui n'est jamais vide

# Opérateurs binaires

Un opérateur binaire, aura deux opérandes, exemples :

# + Addition ou concaténation

+ Peut être un opérateur de concaténation ou d'addition selon les opérandes : si l'un d'entre eux est une string (chaîne de caractères) ou est un objet qui sera converti en string par l'opération interne [[ToPrimitive]], alors ce sera une concaténation, sinon, ce sera une addition.

La concaténation (du latin catena qui veut dire chaîne) est l'action de mettre bout à bout deux éléments (maillons) de chaînes de caractères pour en former une plus grande:

Exemple de concaténation :

var concat = 'Hello ' + 'World!'
console.log(concat) // "Hello World!"

# Comparaisons

  • > et < pour supérieur à et inférieur à ;
  • >= et <= pour supérieur ou égal à et inférieur ou égal à;
  • == (égalité) et === (égalité stricte)

Exemple :

// Extrait de code "o3"
var now = new Date() // Création d'un objet date avec la date (et l'heure) courante
                    // et stockage dans la variable now
var time = now.getHours() // Récupération de l'heure de la date courante
                         // et stockage dans la variable time
var isMorning = now.getTime() < 12 // Est-ce qu'il est moins de 12 heures ?
                                  // Si oui, isMorning aura la valeur true
                                  // Si non, isMorning aura la valeur false

Note : Il existe une et une seule valeur en JS qui n'est pas égale à elle-même : NaN

// Extrait de code "o2"
NaN == NaN // false

NaN veut dire Not a Number mais est de type... number. C'est la valeur que donne JavaScript à une expression dont il ne peut pas calculé le résultat sous forme numérique :

Exemple :

var str = 'Une chaîne de caractère'
var num = 7

var impossible = str / num

console.log(impossible) // NaN

# Opérateurs logiques

&& et ||

&& est l'opérateur ET :

// Extrait de code "o3"
var now = new Date()
// Récupération du jour de la semaine : 0 = dimanche, 1 = lundi... 6 = samedi
var dayOfWeek = now.getDay()

// Est-ce que nous sommes un jour de semaine ?
// Le jour de la semaine doit être
//   inférieur à 6 (samedi)
//   ET
//   supérieur à 0 (dimanche)
// pour que ce soit un jour de semaine :
// isBusinessDay aura la valeur true si nous sommes en semaine, false sinon
var isBusinessDay = dayOfWeek < 6 && dayOfWeek > 0

|| est l'opérateur OU :

var now = new Date()
var dayOfWeek = now.getDay()

// Est-ce que nous sommes le week-end ?
// Le jour de la semaine doit être :
//   6 (samedi)
//   OU
//   0 (dimanche)
// pour qu'on soit le week-end :
// isWeekEnd aura la valeur true si nous sommes le week-end, false sinon
var isWeekEnd = dayOfWeek === 6 || dayOfWeek === 0

# L'opérateur conditionnel

L'opérateur conditionnel est le seul opérateur ternaire en JavaScript est un "raccourci" pour une instruction if : il a trois opérandes : la condition, la valeur ou expression si la condition est remplie, et la valeur ou expression si la condition n'est pas remplie.

// Extrait de code o4
const numberSignAsString = anyNumber < 0 // condition
   ? 'négatif' // valeur si la condition est remplie
   : 'positif' // valeur si la condition n'est pas remplie

Il peut s'écrire sur une seule ligne :

// Extrait de code o4
const numberSignAsString = anyNumber < 0 ? 'négatif' : 'positif'

Et il est équivalent à :

// Extrait de code o5
let numberSignAsString
if (anyNumber < 0) { // condition
   numberSignAsString = 'négatif' // si la condition est remplie
} else {
   numberSignAsString = 'positif' // si la condition n'est pas remplie
}

# Les fonctions

// Extrait de code f1
function add (x, y) {    // Déclaration de la fonction add, qui prend 2 paramètres : x et y
   return x + y         // Opération d'addition ou de concaténation des 2 arguments passés
}
const result = add(2, 3) // Invocation de la fonction add avec 2 arguments : 2 et 3
console.log(result)      // Affichage dans la console du résultat de add(2, 3)

add est le nom de la fonction, x et y sont des paramètres, 2 et 3 sont des arguments.

Une fonction déclarée avec le mot-clé function en début d'instruction est hoistée : sa déclaration et son corps sont placés en tout début d'exécution, ce qui veut dire que l'on peut écrire le code précédent comme ceci :

// Extrait de code f2
const result = add(2, 3)
console.log(result)

function add (x, y) {
   return x + y
}

Ce code ne lèvera pas d'erreur et fonctionnera exactement de la même façon que le premier extrait "f1".