Getter et Setter
EcmaScript 6 a apporté une nouvelle syntaxe pour les "getter" et les "setter". Le principal intérêt des "getter" et des "setter" est de permettre d'opérer des traitements au moment de récupérer ou de modifier une propriété.
Exemple de code :
class Person { constructor(name) { this._name = name; } get name() { console.log("Occasion de faire des traitements"); return this._name; } set name(new_name) { console.log("Occasion de faire des traitements ou de mettre à jour le dom"); this._name = new_name; } } const p = new Person("Dylan"); console.log("name : ", p.name); p.name = "Dupond"; console.log("name : ", p.name);
Import et export
Depuis ES6, on peut gérer les dépendances entre fichiers avec les mots clés "import" et "export"
Ex
export default class Person { constructor(name) { this.name = name; } present() { console.log("hello, I'm " + this.name); } }
De cette façon, dans un autre script, on pourra avoir :
import Person from "./Person.js"; const p = new Person("Bob")
Attention, il faudra penser à appeler votre js en utilisant l'attribut type="module"
<script type="module" src="test.10-module.js">
Paramétrage de Visual Studio Code
Installer “React-Native/React/Redux snippets for es6/es7”
Utiliser les raccourcis clavier suivants :
- irmc (import react component)
- ccs (create component class whitout constructor)
- cccs (create component class with constructor)
- slr (stateless component with return)
Installer "Auto import - ES6, TS, JSX, TSX"
Comme son nom l'indique, cette extension va automatiquement gérer les imports. ATTENTION à bien installer cette application car d'autres ont presque le même nom et ne fonctionnent pas aussi bien.
Installer "Prettier code formatters"
Aller dans File > Preferences > settings > Text editor > formatting et cocher “Format on save”
Activation de emmet pour les fichier javascript :
Aller dans File > preferences > settings puis cliquer sur l'icône en haut à droite pour ouvrir "settings (UI)"
Ajouter dans le fichier settings.json :
"emmet.includeLanguages": { "javascript": "javascriptreact" }
Extension chrome React Developer Tools
Cette extension permet
- de voir le hiérarchie React dans Chrome (cf onglet react dans l’inspecteur de chrome)
- de voir les propriétés states et props dans la fenêtre de droite du même onglet react
- de chercher des objects react grâce au formulaire de recherche
- de voir les propriétés d’un objet React grâce à “$r” dans la console après avoir sélectionné l’objet en question dans l’onglet “React”
Arrow function
Vous étiez habitué.e.s à une déclaration de fonction classique du type :
let maFonction = function () { //code ici }
Et bien avec React, c'est (presque) fini !!!
Voici les "arrow functions" ou "fonctions fléchées" :
let maFonction = () => { //code ici }
Dans le cas où la fonction attend un seul argument (i dans l'exemple ci-dessous), on peut même écrire :
let maFonction = i => { //code ici }
Cela permet d’avoir une syntaxe plus courte que les expressions de fonction classiques.
ATTENTION : la vraie grosse différences avec les fonctions classiques réside dans la valeur de "this" (et oui encore lui -) :
Dans une "arrow function", this dépend de l'endroit où la fonction est déclarée. Par exemple, si la fonction est déclarée dans une méthode d'objet ou dans un constructeur d'objet, alors "this" sera forcément l'objet en question.
En revanche, dans une fonction classique, on sait que "this" dépend du contexte d'appel de la fonction : si la fonction est appelée depuis une instance d'objet, this devient l'instance en question.
Ex :
class Personne { constructor(nom) { this.nom = nom; this.buttonSePresenter = this.createButtonSePresenter(); } createButtonSePresenter(){ const button = document.createElement("button"); button.textContent = "Se présenter"; document.body.appendChild(button); //gestion des événements button.onclick = function() { console.log(this);//qui est this ? } return button; } sePresenter() { console.log("Bonjour, je m'appelle " + this.nom); } } const bob = new Personne("Bob");
Dans ce cas précis, quelle sera la valeur de "this" quand l'internaute cliquera sur le bouton "se présenter" ?
Reprenons cet exemple en utilisant une "arrow function" pour la gestion de l'événement click :
class Personne { constructor(nom) { this.nom = nom; this.buttonSePresenter = this.createButtonSePresenter(); } createButtonSePresenter(){ const button = document.createElement("button"); button.textContent = "Se présenter"; document.body.appendChild(button); //gestion des événements button.onclick = () => { console.log(this);//qui est this ? } return button; } sePresenter() { console.log("Bonjour, je m'appelle " + this.nom); } } const bob = new Personne("Bob");
Dans ce cas, quel sera la valeur de "this" quand l'internaute cliquera sur le bouton "se présenter" ?
Bind
La fonction bind(object) crée une nouvelle fonction qui, lorsqu'elle est appelée, a pour contexte this la valeur passée en paramètre.
Cette méthode est une solution lorsque l'on veut qu'une méhode soit déclarée de façon classique (avec le mot clé function). Par exemple dans le cas de l'utilisation d'une class et que l'on veut que la méthode soit bien stockée dans le prototype du constructeur, il faut utiliser le mot clé function. Le probème récurrent concerne les méthodes gestionnaires d'événement. De façon classique (comme on l'a vu) "this" devient l'objet du dom qui est à la source de l'événement. La solution peut alors consister à "binder" cette méthode dans le constructeur avec une syntaxe du type :
this.handleEventClick = handleEventClick.bind(this);
Méthodes de tableau
map() et littéraux de gabarit
Map est une "Higher-order Functions", c'est à dire qu'elle prendre en paramètre une fonction.
Ellle crée et retourne un nouveau tableau qui transforme tous les éléments du tableau suivant la fonction anonyme (callback) que l'on donnera comme argument de call()
Ex : imaginons que l’on veuille ajouter du code html aux éléments du tableau suivant afin de visualiser une liste à puce.
const fruits = ["Banane", "Pomme", "Kiwi"]; // solution plus classique const liste_fruits = fruits.map(fruit => "<li>" + fruit + "</li>"); // solution utilisant les littéraux de gabarit const liste_fruits = fruits.map(fruit => `<li class="fruit"> ${fruit}</li>`);
indexOf()
La méthode indexOf() renvoie le premier indice pour lequel on trouve un élément donné dans un tableau. Si l'élément cherché n'est pas présent dans le tableau, la méthode renverra -1.
Ex :
let animaux = ['fourmi', 'bison', 'chameau', 'canard']; console.log(animaux.indexOf('bison'));// résultat attendu : 1
Spread operator (ou …)
L'opérateur spread permet de cloner facilement un objet :
const bob = { name: "Bob" }; const bobbis = { ... bob}; console.log(bobbis);// copie de l'objet bob attendue
L'opérateur spread permet également d'étendre un itérable (par exemple une expression de tableau ou une chaîne de caractères) en lieu et place de plusieurs arguments (pour les appels de fonctions) ou de plusieurs éléments (pour les littéraux de tableaux) ou de paires clés-valeurs (pour les littéraux d'objets).
Condition sans if via une structure de contrôle
let i = true; {i && (console.log("hello"))}
Objet décomposé (Object Destructuring)
L'object destructuring existe depuis ECMAScript 6 (2015).
La façon classique de récupérer les propriétés de l'objet p quand p = {nom:"Dylan", prenom:"Bob"} :
const nom = p.nom; const prenom = p.prenom;
Une syntaxe plus courte existe :
const {nom, prenom} = p;
Si les noms des variables sont déjà utilisés :
const {nom:n, prenom:p} = p;
Littéraux de gabarit ou "template string"
Les littéraux de gabarits sont des littéraux de chaînes de caractères permettant d'intégrer des expressions, c'est-à-dire tout ce qui retourne une valeur.
L'usage de base consiste à imbriquer des variables dans les chaînes, entre ${ et }. Elles se verront "remplacées" par leur valeur au moment de l'exécution.
let nb_kiwis = 3; const message = `J'ai ${nb_kiwis} kiwis dans mon panier`; // Résultat : J'ai 3 kiwis dans mon panier
Exemple avec une fonction
function timestamp() { return new Date().getTime() } const message = `Le timestamp actuel est ${timestamp()}`;