Aller au contenu

JavaScript Langage

En JavaScript, tout est objet. Même si vous ne les créez pas vous même, leur usage est obligatoire. Quelques règles :

  • l’accès aux attributs et méthodes d’un objet se fait grâce au point : .
  • il est préférable de terminer chaque instruction par un point-virgule : ;
  • le JavaScript est sensible à la casse

Commentaires#

Comme tout langage de programmation, un bon code est un code bien commenté ! Il existe deux manières d’écrire des commentaires :

Sur une ligne

//ceci est un commentaire sur une ligne

Sur plusieurs lignes

/* ceci est un commentaire sur 
plusieurs lignes */

Variables#

En JavaScript on déclare une variable avec les mots clé var, let ou const et on lui attribue une valeur.

Création de 2 variables

var variable1 = 2;
let variable2 = "Toto";
const variable3 = 54.2;
  • le type d’une variable est implicite
  • la portée d’une variable définie avec var est limitée à la fonction où elle est créée
  • la portée d’une variable définie avec let ou const est limitée au bloc où elle est créée (boucle, test, fonctions, etc.)
  • const ne crée pas de véritables constantes, mais empêche la réassignation

Chaines de caractères#

Pour identifier une chaîne de caractères comme telle, il faut utiliser des guillemets simples ou doubles (' ou ").

Déclaration d’une chaîne de caractère

let texte = 'Cool!';
let chaine = "Super cool...";

Il est possible de concaténer des chaines de caractères et des variables avec le caractère +

Concaténation

let nombre = 42;
let maChaine = 'Le nombre est ' + nombre + '!';

Quelques méthodes d’un objet chaîne de caractères :

  • maChaine.length retourne la longueur d’une chaîne (attention, c’est une propriété)
  • maChaine.substring() retourne une sous chaîne
  • maChaine.split() retourne un tableau de sous-chaines d’une chaîne
  • maChaine.indexOf() retourne la position d’une sous-chaîne au sein d’une chaîne
  • maChaine.replace() remplace une partie de chaîne par une autre

Note : il est possible de dé-spécialiser un caractère avec le backslash \ à placer devant le caractère en question

Tableaux#

Pour déclarer un tableau, la notation littérale est :

Déclaration d’un tableau vide puis remplissage

let monTableau = [];

monTableau[0] = 1;
monTableau[1] = 260.3;
monTableau[2] = "toto";

Déclaration et affectation

let monTableau = [1, 260.3, "toto", 56];

Une fois un tableau instancié, des méthodes sont disponibles. En voici quelques unes intéressantes :

  • monTableau.length la longueur du tableau (attention, c’est une propriété)
  • monTableau.push() ajoute un ou plusieurs éléments en fin de tableau
  • monTableau.pop() retire le dernier élément et retourne cet élément
  • monTableau.shift() retire le premier élément et retourne cet élément
  • monTableau.unshift() ajoute un ou plusieurs éléments en début de tableau
  • monTableau.splice(index, howMany, element1, ...) ajoute ou enlève un ou plusieurs éléments au sein d’un tableau
  • monTableau.sort() trie un tableau
  • monTableau.forEach() parcours un tableau (voir ci-dessous)
  • monTableau.map(fn) applique une fonction pour chaque élément d’un tableau et retourne un nouveau tableau
  • monTableau.filter(fn) renvoi un nouveau tableau de tous les éléments pour lesquels la fonction de callback retourne vrai

Un tableau peut être parcouru avec une boucle for, ou avec la méthode forEach() (attention au support navigateur)

Parcours d’un tableau

let monTableau = [1, 260.3, "toto", 56];

monTableau.forEach(function(element){
    console.log(element);
});

Objets littéraux#

Un objet littéral JS est une paire de clé-valeur entourée d’accolades. Chaque paire est constituée d’une propriété et de sa valeur, séparée par deux-points :. On accède aux propriétés grâce au ., comme dans l’exemple ci-dessous :

Création d’un objet littéral et accès à ses propriétés

let voiture = {
    marque: "Renault",
    gamme: "Mégane",
    couleur: "vert"
};

console.log(voiture.marque); // affiche Renault

Il est également possible d’y stocker des fonctions (le mot-clé this fait référence à l’objet littéral).

Ajout d’une fonction

let voiture = {
    marque: "Renault",
    gamme: "Mégane",
    couleur: "vert",
    getInfos: function(){
        return this.marque + ' ' + this.gamme;
    }
};

console.log(voiture.getInfos()); // affiche Renault Mégane

Booléens#

Les mots clés sont true et false.

En JavaScript, étant donné le typage faible, des «transtypages» sont effectués à l’exécution. La valeur 0 et la chaîne "" sont équivalentes au booléen faux. Toutes les autres valeurs sont considérées comme vraie.

Opérateurs#

Opérateurs
Opérateurs mathématiques +, -, *, /, %, ++, --
Opérateurs d’assignation =, +=, -=, *=, /=, %=
Opérateurs de comparaison de valeur ==, <, <=, >, >=, !=
Opérateurs de comparaison de valeur ET de type ===, !==
Opérateurs logiques &&, ||, !

JavaScript étant un langage à typage faible, il existe deux opérateurs de comparaison

Différence entre == et ===

let str = '8';

str == 8      // true
str === 8     // false

L’opérateur % (modulo) est particulièrement intéressant pour définir des cycles.

Exemple: l’angle est toujours entre 0 et 360

let angle = 300;
angle += 90;
angle %= 360;
// angle vaut 30;

Tests#

Les structures de tests sont classiques.

Test de condition simple (condition doit être un résultat booléen ex: a==b renvoie un boolean)

if (condition) {
    // Code à exécuter si la condition est vraie
}

Test de condition complet

if (condition) {
    // Code à exécuter si la condition est vraie
} else {
    // Code à exécuter sinon
}

Test à choix multiple (à utiliser pour tester plusieurs valeurs possibles d’une variable)

switch (variable) {
    case valeur1:
        // Code à exécuter si variable==valeur1
        break;
    case valeur2:
        // Code à exétuter si variable==valeur2
        break;
    // On peut mettre autant de 'case' que nécessaire
    default :
        // Code à exécuter si variable ne correspond à aucune valeur ci-dessus
}

Boucles#

Boucle "Tant que la condition est vraie, faire ..."

while (condition) {
    // Code à exécuter
}

Boucle "Faire ... , tant que la condition est vraie" (s’exécute au minimum une fois)

do {
    // Code à exécuter
} while (condition)

Boucle for. Ex: répéter 100 fois un bloc de code

// Pour i initialisé à 0
// tant que i est inférieur ou égal à 100
// incrémente i de 1 à chaque 'tour'
for (let i = 0; i <= 100; i++) {
    // Code à exécuter
}

Boucle sur objet littéral

for (let key in obj) {
    // obj[key]
}

Boucle sur tableau (rappel)

tableau.forEach(function (elem) {
    // elem
});
// ou
let newTab = tableau.map(function (elem) {
    return elem;
});

Débranchements#

  • pour sortir subitement d’une boucle, l’instruction est break
  • pour passer directement à l’itération suivante, l’instruction est continue

Affiche les nombres de 1 à 100 SAUF les dizaines justes

let i = 0;
// boucle sans fin
while (true) {
    i++;
    // si i est multiple de 10
    // on va a l’itération suivante
    if ( !(i%10) ) {
        continue;
    }
    // si i est supérieur à 100
    // on sort de la boucle
    if (i>100) {
        break;
    }
    // sinon on écrit
    console.log("La valeur de i est " + i);
}

Exercice - Jeu nombre#

  • (préparez éventuellement une nouvelle page dans Flight. Voir les bonnes pratiques)

  • créez un fichier "javascript.js"

  • liez-le à la page HTML à l'aide d'une balise <script>
  • dans ce fichier, générez un nombre aléatoire entre 0 et 100
    • vous aurez besoin de Math.round(), Math.random()
  • l’afficher en console (console.log())

Ensuite :

  • demandez au joueur de trouver ce nombre (let msg = prompt('message'))
  • vérifiez si le nombre proposé est plus grand ou plus petit
    • dans les 2 cas, redemandez à nouveau au joueur de trouver, mais en précisant dans le message si le chiffre est plus grand ou plus petit
  • affichez quand c’est gagné (alert('message'))

Enfin :

  • affichez le nombre de fois nécessaires pour trouver le nombre
  • calculez le temps nécessaire qu’il a fallu pour trouver (vous aurez besoin de Date.now(), en millisecondes)

Fonctions#

La déclaration d’une fonction est très classique :

Déclaration et appel d’une fonction action()

// declaration
function action (param1, param2) {
    console.log("action" + param1);
}

// appel
action("toto", 8);

Une fonction peut prendre plusieurs paramètres. Elle peut être appelée même si son prototypage n’est pas respecté. Pour cela, l’objet arguments peut être pratique : il contient les arguments passés en paramètres.

Utilisation de arguments

// declaration
function concat (separateur) {
    let result = "";
    for (let i = 1; i < arguments.length; i++) {
        result += arguments[i];
        if (i != arguments.length - 1) {
            result += separateur;
        }
    }
    return result;
}

console.log(concat('-', "Pomme", "Poire", "Abricot")); // Pomme-Poire-Abricot

Fonctions fléchées#

En ES6, les fonctions fléchées (arrow functions) font leur apparition. C’est une syntaxe raccourcie de la notation classique. Très utile dans le cas de fonctions anonymes

Exemple de fonctions fléchées

// ES5
[0, 1, 2].map(function (el) {
  return el + 2
})

// ES6
[0, 1, 2].map(el => el + 2)

// ES6 avec corps de fonction
[0, 1, 2, 3, 4].map(el => {
  if (el < 3) {
    return el
  }
})

Notez que le this dans une fonction fléchée est bindé automatiquement.

Paramètres par défaut#

En ES6 toujours, un paramètre de fonction peut avoir une valeur par défaut

function foo (param = 42) {
    return param;
}

foo()      // 42
foo(3.14)  // 3.14

Attention au support navigateur avec ES6 et plus

Objets et méthodes globaux#

Date#

La gestion des dates se fait via l’objet Date.

Création d’une date

let today = new Date();

today.getMonth(); // le mois en cours
today.getFullYear(); // l'annee en cours
today.getTime(); // le timestamp actuel

Date.now() // le timestamp actuel (méthode statique)

Plus d’infos sur les dates en JS

Math#

L’objet Math, comme son nom l’indique, contient des propriétés et méthodes mathématiques, tels que :

  • Math.PI pour le nombre PI
  • Math.abs(nb) pour la valeur absolue
  • Math.cos(nb), Math.sin(nb), Math.tan(nb) pour les fonctions trigonométriques (en radians)
  • Math.floor(nb) arrondi à l’entier inférieur
  • Math.ceil(nb) arrondi à l’entier supérieur
  • Math.round(nb) arrondi à l’entier le plus proche
  • Math.min(nb1, nb2), Math.max(nb1, nb2) renvoi les minimums ou maximums de deux arguments
  • Math.random() retourne un nombre aléatoire entre 0 et 1
  • Math.pow(nbre, exp), Math.sqrt(nb) respectivement la puissance et la racine carré

Plus d’infos sur l’objet Math en JS

JSON#

L’objet JSON permet de manipuler des objets JSON. Il contient deux méthodes :

  • JSON.parse() traite une chaine de caractères et crée un objet JSON (objet littéral JavaScript)
  • JSON.stringify() convertit un objet littéral JavaScript (JSON) en chaine de caractères

Créer un objet JS à partir d’une chaine JSON (utile pour les appels AJAX)

let jsonString = '{"couleur": "bleu"}';

let jsonObj = JSON.parse(jsonString);
console.log(jsonObj.couleur); // == bleu

setTimeout() et requestAnimationFrame#

  • La fonction setTimeout(fn, t) exécute la fonction fn après t millisecondes

Lancer une fonction après attente de 1s

setTimeout(function () {
    console.log('hello');
}, 1000);

Une fonction qui se relance en boucle toutes les secondes

function loop () {
  //do something...

  setTimeout(loop, 1000);
}

loop();
  • La fonction requestAnimationFrame(fn) exécute la fonction fn lors du prochain rafraichissement de l’écran (soit 60 fois par seconde pour un écran classique 60Hz). Très utile pour créer des animations performantes (mais pas uniquement)

Déplacer un élément dans la page pendant 2s

let start = null;
function step (timestamp) {
  if (!start) {
    start = timestamp;
  }
  const progress = timestamp - start;

  // do your stuff with progress. ex:
  element.style.transform = 'translateX(' + (progress/10) + 'px)';

  if (progress < 2000) {
    requestAnimationFrame(step);
  }
}

requestAnimationFrame(step);

Pour aller plus loin sur le MDN

Gestion des exceptions#

JavaScript dispose du block try...catch, comme dans beaucoup de langages

try {
  // something
} catch (e) {
  // if fails
  throw new Error(e)
}

Exercice - Traitement géo#

Voici une liste de coordonnées (île de la Cité et île St-Louis) :

let polygons = [[[[48.857757564566924,2.339316137485028],[48.856806083163775,2.3410084512700275],[48.85500429223433,2.3431007664951173],[48.85424556800601,2.3448607983431384],[48.85346104822773,2.3470146522513193],[48.852722069967,2.348637735017842],[48.852246283670866,2.3498685086796596],[5.513516521235,3.512416589454425],[48.85158827389591,2.352683903431068],[48.85202863524094,2.352391594686386],[48.85372424333016,2.3520685166001587],[48.8546352926156,2.3512762060553634],[48.85546534530812,2.3495454305934325],[48.855769019683805,2.3483223492670007],[48.85667497062573,2.3452915691247744],[48.857282302859346,2.3412992470592533],[48.857757564566924,2.339316137485028]]],[[[48.85374747782521,2.3530207906753438],[48.85253332128681,2.3532408660072544],[48.85163103910017,2.353884163131301],[48.85105178764471,2.3558479122468126],[48.849893264629145,2.3592336865839],[48.84948109132219,2.360317134371768],[48.85032771390132,2.36001241468143],[48.85104064812796,2.3601478456549136],[48.85167559662685,2.35960612176098],[48.85373633890825,2.353410154724109],[48.85374747782521,2.3530207906753438]]]]

Nous voulons réaliser un traitement qui doit :

  • arrondir les coordonnées à 5 chiffres après la virgule
    • utilisez Number(nb.toFixed(val))
  • inverser latitude/longitude (donc longitude en premier)
    • utilisez Array.reverse()
  • supprimer les points hors des bornes 48.84 > latitude > 48.86 et 2.33 > longitude > 2.37
  • faites le traitement à votre guise

Vous pouvez tester le résultat sur geojson.io :

  • ajoutez votre variable finale dans l’objet geoJSON ci-dessous
  • récupérez le geoJSON en mode texte avec JSON.stringify(val)
let geojson = {
  "type": "FeatureCollection",
  "features": [
    {
      "type": "Feature",
      "properties": {},
      "geometry": {
        "coordinates": [],
        "type": "MultiPolygon"
      }
    }
  ]
};