1. Prise en main
Pour prendre en main le language, nous allons exécuter des scripts Javascript directement dans la console à l’aide de Node.js (mais nous n’utiliserons que du javascript "pur", sans les spécificités de Node).
Téléchargez et installez Node.js via ce lien : https://nodejs.org/en/download/
En cas de problème vous pouvez aussi utiliser JS Bin pour écrire les programmes en ligne : http://jsbin.com/?js,console
Pour tester l’installation, créez un fichier javascript (exercice_1.js) contenant :
console.log("Hello world!");
Puis exécutez le fichier avec node
:
> node exercice_1.js
Hello world!
2. Variables
Déclaration
En javascript les variables peuvent être déclarées de 3 façons différentes :
-
var
-
const
(ES6) -
let
(ES6)
Les 3 mots clés s’utilisent de la même façon :
var a = 42;
const b = 42;
let c = 42;
Une variable déclarée avec const
doit toujours être initialisée.
Lorsque la variable n’est pas initialisée (var a;
ou let a;
), la valeur de a
est undefined
.
Scope
Une variable déclarée avec var
est accessible dans l’ensemble du contexte courant (la fonction actuelle), tandis qu’une déclaration avec let
ou const
rendra la variable accessible uniquement dans le bloc courant.
function ex_var() {
var a = 5;
if(true) {
var b = 8;
console.log(b); // 8
}
console.log(b); // 8
}
function ex_let() {
var a = 5;
if(true) {
let b = 8;
console.log(b); // 8
}
console.log(b); // error, b n'existe pas
}
3. Fonctions
Pour déclarer une fonction :
function name() {
// contenu
}
name(); //appel de cette fonction
Une variable peut aussi contenir une fonction (tout comme n’importe quel autre type) :
let name = function() {} //fonction anonyme
name(); //appel
Les fonctions anonymes sont très utiles pour être passées en callback d’une autre fonction :
function exemple1() {
//contenu
}
fonctionQuiAccepteUneAutreFonction(exemple1)
//OU
fonctionQuiAccepteUneAutreFonction(function(){
//contenu
})
Lors de l’appel d’une fonction, vous pouvez passer un paramètre de deux façons :
const obj = { a : 1 }
maFonction(obj) // la variable
maFonction({ a : 1 }) // directement un nouvel objet
this
La variable this
est accessible partout dans votre code mais ne représente pas toujours la même chose.
Cette variable sera très utile lorsque nous utiliserons javascript avec Vue.js et Node.
Dans l’environnement global (à l’extérieur de toute fonction) this
va pointer vers le contexte global :
this.a = "Hello";
console.log(a); //Hello
console.log(this.a); //Hello
Lors de l’appel d’une fonction, on distingue deux cas de figure :
Appel classique
Par défaut, this
à l’intérieur d’une fonction va pointer vers l’objet global :
function f() {
console.log(this.a);
}
global.a = 8;
f();
On peut appeler cette fonction avec un autre contexte, en utilisant call
ou apply
:
function f(param1, param2) {
console.log(this.a)
console.log(param1+param2)
}
f.call({a: 24}, 1, 2) //24 (les arguments sont 1 et 2)
f.apply({a: 42}, [5, 6]) //42 (les arguments sont 5 et 6)
Bind
L’appel à la méthode bind
va créer une nouvelle fonction où this
est lié pour toujours à l’objet passé en paramètre.
function f() {
console.log(this.a)
}
let g = f.bind({a: 24})
g() //24
let h = f.bind({a: 42})
h() //42
f.call({a: 112}) //112
Arrow-functions (ES6)
ES6 a apporté les arrow-functions (ou fonctions flêchées), une nouvelle manière de définir une fonction anonyme :
() => {
//contenu
}
//au lieu de :
function() {
//contenu
}
Les paramètres se situent à gauche de la flêche (on peut omettre les parentèse si on passe un seul paramètre).
À droite de la flêche se trouve le corp de la fonction.
let f = (e,f) => { return e+f }
let f = e => { return e+1 } // 1 seul paramètre = parenthèses non nécessaires
let f = e => e+1 // Pas d'accolade = retourner la valeur de l'expression
L’intérêt principal de cette notation : Une fonction flêchée garde la valeur this
du contexte parent.
//Avant pour qu'un callback puisse modifier le contexte il fallait faire :
function f() {
//...
let self = this; // on garde une référence au contexte
loadData(function() {
//this = cette fonction anonyme et non plus la fonction f
self.mydata = "...";
})
//...
}
//Maintenant
function f() {
//...
loadData( () => {
//this = l'objet englobant
this.mydata = "...";
})
//...
}
Questions
3.1. On commence doucement : créez une fonction qui retourne le triple de l’entier passé en paramètre
3.2. Analysez dans votre tête (ou sur papier) le code suivant (sans l’exécuter). Quelle est d’après vous la sortie du programme ?
var b=2;
function a() {
var e=5;
console.log(b);
console.log(c);
console.log(d);
console.log(e);
}
var c=3;
a();
var d=4;
Les variables sont accessibles uniquement dans le scope actuel et les scopes enfant
var b=2; //scope global
function a() {
console.log("a");
var e=5; //scope a
console.log(b);
console.log(c);
console.log(e);
console.log(d);
}
function f() {
console.log("f");
var d=6; //scope f
console.log(d);
}
f();
a();
var c=3; //scope global
3.3. Afin de bien comprendre les portées du scope, créez une fonction add
accessible uniquement depuis une fonction sum
.
* La fonction add
retourne la somme des 2 nombres passés en paramètre.
* La fonction sum
utilise add
pour additionner les 4 nombres passés en paramètre et retourne le résultat
Le scope global ne doit pas avoir accès à la fonction add
.
3.4. Écrivez de deux manières une fonction pow
qui prend en paramètre b
et n
, et retourne b puissance n
.
3.5.
function qu3_5(a, b, c) {
return a * c(b);
}
// Appelez cette fonction avec des paramètres cohérents
4. Chaînes de caractères
Quelques façons d’écrire des chaînes de caractère :
let str1 = "Ceci est une string plutôt simple";
let str2 = 'Une autre string';
let str3 = "Ceci est une string avec \" un caratère échappé";
let number = 8;
let str4 = "Le nombre est " + number;
let str5 = `Le nombre est ${number}`; //particulièrement pratique lorsqu'on a de nombreuses variables à insérer
let str6 = "Multiligne \
string";
let str7 = `Multiligne
string`;
Les chaînes sont des objets et donnent accès à de nombreuses méthodes (cf doc)
let str = "Test de string";
str.length; //14
str.replace(" ", "."); //Test.de.string
Questions
4.1. Créez une fonction qui affiche dans la console l’inverse de la chaîne passée en paramètre. ex: "Hello" → "olleH"
4.2. Faites en sorte que le code suivant remplace les caractères a
par b
, b
par c
et ainsi de suite
Indice : Renseignez-vous au sujet de String.fromCharCode() et String.CharCodeAt(), le code ASCII pourrait être utile.
Essayez d’utiliser Map.
function replace(str) {
// votre code
}
replace("Je suis ton père", my_fn);
5. Les tableaux
Les tableaux (objet Array
) représentent une liste ordonnée de valeurs. Numérotés à partir de 0, chaque élément peut être d’un type différent.
let arr = new Array(0, 1, 3);
let arr= [0, 1, 3];
console.log(arr[2]); //3
arr.push(8); //[0,1,3,8]
Questions
5.1. Map
var arr = [ { a: 1, b: 2 }, { a:2 , b: 4 }, { a: 9, b: 1 }, { a: 19, b: 29 }, { a: 187, b: 4 } ];
Remplacez tout les éléments de ce tableau par la valeur de la propriété b
. Écrivez votre solution de 2 manières : avec et sans map
.
5.2. Filter
var arr = [ { a: 1, b: 2 }, { a:2 , b: 4 }, { a: 9, b: 1 }, { a: 19, b: 29 }, { a: 187, b: 4 } ];
Écrivez une fonction qui prend ce tableau en paramètre et garde uniquement les éléments avec a > 3
.
5.3. Reduce
var arr = [ "Luke Skywalker", "Maître Yoda", "R2D2", "Padmé Amidala", "Anakin Skywalker", "Obi-Wan Kenobi" ];
Écrivez une fonction qui retourne la chaîne de caractère Luke Skywalker, Anakin Skywalker, Obi-Wan Kenobi
etc… en utilisant reduce
.
5.4. Écrivez une autre fonction qui retourne cette même chaîne mais sans les membres de la famille Skywalker.
5.5. Écrivez une fonction qui prend une chaîne de caractère et retourne un objet représentant le nombre d’apparition de chaque lettre (hors espaces).
Combinez Filter et Reduce.
ex. countLetters("il dit qu’il voit pas le rapport") // ⇒ { "'" : 1, a: 2, d: 1, e: 1, i: 4, l: 3, o: 2, p: 3, q: 1, r: 2, s: 1, t: 3, u: 1, v: 1 }
var countLetters = function(string){
// votre code
};
6. Les objets
Le concept d’objet en javascript est le même que dans les autres languages : un conteneur qui englobe des propriétés et des méthodes.
Les méthodes et propriétés d’un objet sont accessible via le .
ou les crochets :
object.property
object["property"]
object.method()
object["method"]()
Tout est objet en javascript, même les types primitifs (nombres, chaînes de caratère, booléens etc…)
console.log("Hello".length) //5
Les objets peuvent être utilisés pour stocker des paires clé/valeur (comme avec un objet JSON ou les structures en C) :
let obj = new Object();
obj.a = 42;
obj.b = 81;
let obj = {
a: 42,
b: 81
}
obj.c //undefined
Questions
6.1. Créez un objet représentant un film (titre, synopsys, année de sortie) ainsi que son réalisateur (sous-objet avec nom/prénom/date de naissance).
6.2. Créez un tableau contenant les films Titanic, Interstellar, La ligne verte avec leurs infos. Affichez ensuite le contenu du tableau dans la console (en mettant en forme les infos du film sur chaque ligne)
6.3. Écrivez une fonction prenant en paramètre ce tableau, et un 2ème paramètre search. La fonction retourne un tableau contenant les films dont le champ titre contient ce paramètre search.
Indice : utilisez filter
function search_movie(arr, search) {
// votre code
}