Funkcija klasa protiv tvornice: istraživanje puta prema naprijed

Discover Functional JavaScript proglašen je jednom od najboljih knjiga o funkcionalnom programiranju od strane BookAuthority !

ECMAScript 2015 (aka ES6) dolazi sa classsintaksom, tako da sada imamo dva konkurentska uzorka za stvaranje objekata. Da bih ih usporedio, stvorit ću istu definiciju objekta (TodoModel) kao klasu,a zatim kao tvornička funkcija.

TodoModel kao razred

class TodoModel { constructor(){ this.todos = []; this.lastChange = null; } addToPrivateList(){ console.log("addToPrivateList"); } add() { console.log("add"); } reload(){} }

TodoModel kao tvornička funkcija

function TodoModel(){ var todos = []; var lastChange = null; function addToPrivateList(){ console.log("addToPrivateList"); } function add() { console.log("add"); } function reload(){} return Object.freeze({ add, reload }); }

Kapsulacija

Prvo što primjećujemo jest da su svi članovi, polja i metode objekta klase javni.

var todoModel = new TodoModel(); console.log(todoModel.todos); //[] console.log(todoModel.lastChange) //null todoModel.addToPrivateList(); //addToPrivateList

Nedostatak inkapsulacije može stvoriti sigurnosne probleme. Uzmimo primjer globalnog objekta koji se može izravno izmijeniti iz Developer Consolea.

Kada upotrebljavamo tvorničke funkcije, samo su metode koje izlažemo javne, a sve ostalo je enkapsulirano.

var todoModel = TodoModel(); console.log(todoModel.todos); //undefined console.log(todoModel.lastChange) //undefined todoModel.addToPrivateList(); //taskModel.addToPrivateList is not a function

ovaj

thisProblemi s gubitkom konteksta još uvijek postoje kod upotrebe klase. Na primjer, thisgubi kontekst u ugniježđenim funkcijama. Ne samo da smeta tijekom kodiranja, već je i stalni izvor bugova.

class TodoModel { constructor(){ this.todos = []; } reload(){ setTimeout(function log() { console.log(this.todos); //undefined }, 0); } } todoModel.reload(); //undefined

ili thisgubi kontekst kada se metoda koristi kao povratni poziv, poput DOM događaja.

$("#btn").click(todoModel.reload); //undefined

Kod upotrebe tvorničke funkcije nema takvih problema, jer se uopće ne koristi this.

function TodoModel(){ var todos = []; function reload(){ setTimeout(function log() { console.log(todos); //[] }, 0); } } todoModel.reload(); //[] $("#btn").click(todoModel.reload); //[]

ovo i funkcija strelice

Funkcija strelice djelomično rješava probleme s thisgubitkom konteksta u klasama, ali istodobno stvara novi problem:

  • this više ne gubi kontekst u ugniježđenim funkcijama
  • this je gubljenje konteksta kada se metoda koristi kao povratni poziv
  • funkcija strelica promiče upotrebu anonimnih funkcija

Refaktorirao sam TodoModelpomoću funkcije strelice. Važno je napomenuti da u procesu refaktoriranja na funkciju strelice možemo izgubiti nešto vrlo važno za čitljivost, naziv funkcije. Pogledajte primjer:

//using function name to express intent setTimeout(function renderTodosForReview() { /* code */ }, 0); //versus using an anonymous function setTimeout(() => { /* code */ }, 0);

Discover Functional JavaScript proglašen je jednim odnajbolje nove knjige o funkcionalnom programiranju by BookAuthority !

Za više o primjeni tehnika funkcionalnog programiranja u Reactu pogledajte Functional React .

Naučite funkcionalni React , na način temeljen na projektu, uz Funkcionalnu arhitekturu s Reactom i Reduxom .

Slijedite na Twitteru