Descoperiți JavaScript funcțional a fost numit unul dintre cele mai bune cărți noi de programare funcțională de BookAuthority!
ECMAScript 2015 (alias ES6) vine cu class
sintaxă, așa că acum avem două modele concurente pentru crearea obiectelor. Pentru a le compara, voi crea aceeași definiție a obiectului (TodoModel) ca o clasă, și apoi ca funcție din fabrică.
class TodoModel {
constructor(){
this.todos = [];
this.lastChange = null;
}
addToPrivateList(){
console.log("addToPrivateList");
}
add() { console.log("add"); }
reload(){}
}
TodoModel ca funcție din fabrică
function TodoModel(){
var todos = [];
var lastChange = null;
function addToPrivateList(){
console.log("addToPrivateList");
}
function add() { console.log("add"); }
function reload(){}
return Object.freeze({
add,
reload
});
}
Incapsularea
Primul lucru pe care îl observăm este că toți membrii, câmpurile și metodele unui obiect de clasă sunt publice.
var todoModel = new TodoModel();
console.log(todoModel.todos); //[]
console.log(todoModel.lastChange) //null
todoModel.addToPrivateList(); //addToPrivateList
Lipsa încapsulării poate crea probleme de securitate. Luați exemplul unui obiect global care poate fi modificat direct din Consola pentru dezvoltatori.
Atunci când se utilizează funcția din fabrică, numai metodele pe care le expunem sunt publice, orice altceva este încapsulat.
var todoModel = TodoModel();
console.log(todoModel.todos); //undefined
console.log(todoModel.lastChange) //undefined
todoModel.addToPrivateList(); //taskModel.addToPrivateList
is not a function
acest
this
pierderea problemelor de context sunt încă acolo atunci când se utilizează clasa. De exemplu, this
pierde contextul în funcțiile imbricate. Nu este doar enervant în timpul codării, ci este și o sursă constantă de bug-uri.
class TodoModel {
constructor(){
this.todos = [];
}
reload(){
setTimeout(function log() {
console.log(this.todos); //undefined
}, 0);
}
}
todoModel.reload(); //undefined
sau this
pierde contextul când metoda este utilizată ca apel invers, ca la un eveniment DOM.
$("#btn").click(todoModel.reload); //undefined
Nu există astfel de probleme atunci când se utilizează o funcție din fabrică, deoarece nu o folosește this
deloc.
function TodoModel(){
var todos = [];
function reload(){
setTimeout(function log() {
console.log(todos); //[]
}, 0);
}
}
todoModel.reload(); //[]
$("#btn").click(todoModel.reload); //[]
aceasta și funcția săgeată
Funcția săgeată rezolvă parțial this
pierderea problemelor de context în clase, dar în același timp creează o nouă problemă:
-
this
nu mai pierde contextul în funcțiile imbricate -
this
pierde contextul când metoda este utilizată ca apel invers - funcția săgeată promovează utilizarea funcțiilor anonime
Am refactorizat TodoModel
folosind funcția săgeată. Este important să rețineți că în procesul de refactorizare a funcției săgeată putem pierde ceva foarte important pentru lizibilitate, numele funcției. Uită-te de exemplu la:
//using function name to express intent
setTimeout(function renderTodosForReview() {
/* code */
}, 0);
//versus using an anonymous function
setTimeout(() => {
/* code */
}, 0);
Descoperiți JavaScript funcțional a fost numit unul dintre cele mai bune cărți noi de programare funcțională de BookAuthority!
Pentru mai multe despre aplicarea tehnicilor funcționale de programare în React, aruncați o privire Reactie functionala.
Învăța funcțional React, într-un mod bazat pe proiecte, cu Arhitectură funcțională cu React și Redux.