Fonctions fléchées

A la conquête de l'ES6 partie 2

Arrow function

Pour ce second article dédié à l’ES6, j’ai décidé de te parler des fonctions fléchées (arrow function) qui est une nouvelle manière d’écrire les fonctions en remplaçant function() par () =>.

//syntaxe classique
var demo = function(){
  console.log("demo");
}

//syntaxe es6
var demo = () => {
  console.log("demo");
}

Si ma fonction ne contient qu’une seule instruction, alors je peux enlever les parenthèses et donc écrire sur une seule ligne, histoire d’avoir un code encore plus clean, ou pas…

var demo = () => console.log("demo");

Pour une opération simple comme une addition par exemple, tu n’as même pas besoin d’écrire le mot-clé return pour retourner la valeur, c’est automatique. Ouais t’as tout compris, on est en train de désosser la fonction, c’est cool nan ?

let addition = (a,b) => a+b;
console.log(addition(2,3));

Si tu passes un seul argument à ta fonction, tu peux même enlever les parenthèses, dans le cas d’une fonction qui calcule le double d’un nombre par exemple. Je kiffe trop le truc, j’ai l’impression que si je continue, il ne va plus rien rester de la fonction haha.

//version es6
let double = a => a*2 ;

//version classique
function double_v2(){
  return a*2;
}

Bon personnellement, je n’ai jamais été fan de tout ce qui s’écrit sur une seule ligne, mais faut savoir que maintenant il y a plein de trucs qui vont être possibles au niveau nettoyage de code.

//normale
function add_event(e){
  $(e).click(function(){
    alert("click sur bouton")
  });
}

//es6
add_event = e => $(e).click( () => alert("click sur bouton") );

//lancement de la fonction
add_event(".button");

Bon pour certains cas, c’est vrai que c’est vraiment très propre.

//normal
let calcul = function(){
  return function(a, b){ 
    return a + b 
  };
}

//version es6
let calcul = () => (a, b) => a + b;

THIS is cool

Changer la façon d’écrire une fonction, c’est bien, mais apporter une nouvelle fonctionnalité, c’est mieux, et c’est ce que fait ES6 ! En effet, la création d’une fonction fléchée ne crée pas de contexte et donc ne redéfini pas le this. Fini de se prendre la tête pour sauvegarder notre this.

Pour illustrer la nouvelle fonctionnalité, c’est simple, regarde l’exemple suivant, le premier this va afficher mon bouton et le second qui se trouve dans le each va afficher les éléments li. Bon la à la limite, rien de problématique dans cet exemple mais c’est juste pour piger que le this a été redéfini dans la fonction de callback du each.

$(".button").click(function(){
  console.log(this); //affiche le bouton
  $("li").each(function(cle,valeur){
    console.log(this); //affiche les li
  });
});

La fonction fléchée nous permet d’empêcher cette redéfinition. Si tu exécutes le code suivant, tu verras que le this dans la fonction de callback du each sera le même que celui du bouton.

$(".button").click(function(){
  console.log(this); //affiche le bouton
  $("li").each((cle,valeur) => {
    console.log(this); //affiche le bouton pour chaque élément li
  });
});

C’est vrai que l’exemple que je viens de citer n’a aucun intérêt, mais cette fonctionnalité prend tout son sens lorsque tu vas écrire du code JavaScript en mode orienté objet, façon PHP. Dans ce paradigme, le this est super important et lorsqu’il change (par redéfinition) il devient totalement inutile et il faut utiliser des hacks…

Et c’est sans surprise que le code suivant m’affiche un joli undefined.

class obj {
  
  constructor(){
    this.result = 0;
    this.ajout([1,5,4]);

    this.affichage();
  }
  
  ajout(tableau){

    tableau.forEach(function(valeur, key){
      //ici le this est redéfini, ce n'est plus le this de la classe
      this.result += valeur;
    });
  }
  
  affichage(){
    console.log(this.result);
  }

}

new obj();

Grâce aux fonctions fléchées, le this n’est pas redéfini, donc maintenant ce code fonctionne. Et j’en ai même profité pour le cleaner un peu !

class obj {
  
  constructor(){
    this.result = 0;
    this.ajout([1,5,4]);

    this.affichage();
  }
  
  ajout(tableau){
    tableau.forEach((valeur, key) => this.result += valeur );
  }
  
  affichage(){
    console.log(this.result);
  }

}

new obj();

16/04/2016

Yann Vangampelaere - nouslesdevs -

Sinon jete un coup d’oeil aux autres catégories

Ma boîte aux lettres

Tu veux me demander quelque chose ?