Discover Functional JavaScript a été nommé l'un des meilleurs nouveaux livres de programmation fonctionnelle par BookAuthority !
ECMAScript 2015 (alias ES6) est livré avec la class
syntaxe, nous avons donc maintenant deux modèles concurrents pour créer des objets. Afin de les comparer, je vais créer la même définition d'objet (TodoModel) qu'une classe,puis comme fonction d'usine.
TodoModel en tant que classe
class TodoModel { constructor(){ this.todos = []; this.lastChange = null; } addToPrivateList(){ console.log("addToPrivateList"); } add() { console.log("add"); } reload(){} }
TodoModel en tant que fonction d'usine
function TodoModel(){ var todos = []; var lastChange = null; function addToPrivateList(){ console.log("addToPrivateList"); } function add() { console.log("add"); } function reload(){} return Object.freeze({ add, reload }); }
Encapsulation
La première chose que nous remarquons est que tous les membres, champs et méthodes d'un objet de classe sont publics.
var todoModel = new TodoModel(); console.log(todoModel.todos); //[] console.log(todoModel.lastChange) //null todoModel.addToPrivateList(); //addToPrivateList
Le manque d'encapsulation peut créer des problèmes de sécurité. Prenons l'exemple d'un objet global qui peut être modifié directement depuis la Developer Console.
Lorsque vous utilisez la fonction de fabrique, seules les méthodes que nous exposons sont publiques, tout le reste est encapsulé.
var todoModel = TodoModel(); console.log(todoModel.todos); //undefined console.log(todoModel.lastChange) //undefined todoModel.addToPrivateList(); //taskModel.addToPrivateList is not a function
ce
this
les problèmes de contexte perdant sont toujours présents lors de l'utilisation de la classe. Par exemple, this
perd du contexte dans les fonctions imbriquées. Ce n'est pas seulement ennuyeux lors du codage, mais c'est aussi une source constante de bogues.
class TodoModel { constructor(){ this.todos = []; } reload(){ setTimeout(function log() { console.log(this.todos); //undefined }, 0); } } todoModel.reload(); //undefined
ou this
perd son contexte lorsque la méthode est utilisée comme rappel, comme sur un événement DOM.
$("#btn").click(todoModel.reload); //undefined
Il n'y a pas de tels problèmes lors de l'utilisation d'une fonction d'usine, car elle ne l'utilise pas this
du tout.
function TodoModel(){ var todos = []; function reload(){ setTimeout(function log() { console.log(todos); //[] }, 0); } } todoModel.reload(); //[] $("#btn").click(todoModel.reload); //[]
cette fonction et flèche
La fonction flèche résout partiellement les this
problèmes de contexte perdant dans les classes, mais crée en même temps un nouveau problème:
this
ne perd plus de contexte dans les fonctions imbriquéesthis
perd son contexte lorsque la méthode est utilisée comme rappel- la fonction flèche favorise l'utilisation de fonctions anonymes
J'ai refactoré la fonction en TodoModel
utilisant la flèche. Il est important de noter que dans le processus de refactorisation de la fonction de flèche, nous pouvons perdre quelque chose de très important pour la lisibilité, le nom de la fonction. Regardez par exemple:
//using function name to express intent setTimeout(function renderTodosForReview() { /* code */ }, 0); //versus using an anonymous function setTimeout(() => { /* code */ }, 0);
Discover Functional JavaScript a été nommé l'un desmeilleurs nouveaux livres de programmation fonctionnelle par BookAuthority !
Pour en savoir plus sur l'application des techniques de programmation fonctionnelle dans React, jetez un œil à Functional React .
Apprenez React fonctionnel , de manière basée sur un projet, avec une architecture fonctionnelle avec React et Redux .
Suivre sur Twitter