Fonction classe vs usine: explorer la voie à suivre

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 classsyntaxe, 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

thisles problèmes de contexte perdant sont toujours présents lors de l'utilisation de la classe. Par exemple, thisperd 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 thisperd 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 thisdu 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 thisproblè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ées
  • this 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 TodoModelutilisant 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