Автор оригинала: Cristian Salcescu.
Откройте для себя функциональный JavaScript был назван одним из Лучшие новые функциональные программирования книги BookAuthority !
Ecmascript 2015 (AKA ES6) поставляется с Класс Синтаксис, поэтому теперь у нас есть две конкурирующие шаблоны для создания объектов. Для того, чтобы сравнить их, я создам одно и то же определение объекта (тододорел) как класс, а затем как функция завода.
Топододол как класс
class TodoModel {
constructor(){
this.todos = [];
this.lastChange = null;
}
addToPrivateList(){
console.log("addToPrivateList");
}
add() { console.log("add"); }
reload(){}
}Топододол как заводская функция
function TodoModel(){
var todos = [];
var lastChange = null;
function addToPrivateList(){
console.log("addToPrivateList");
}
function add() { console.log("add"); }
function reload(){}
return Object.freeze({
add,
reload
});
}Инкапсуляция
Первое, что мы замечаем, состоит в том, что все члены, поля и методы объекта класса являются общедоступными.
var todoModel = new TodoModel(); console.log(todoModel.todos); //[] console.log(todoModel.lastChange) //null todoModel.addToPrivateList(); //addToPrivateList
Отсутствие инкапсуляции может создавать проблемы с безопасностью. Возьмите пример глобального объекта, который можно изменять непосредственно из консоли разработчиков.
При использовании заводской функции, только методы, которые мы выставляем, являются публичными, все остальное инкапсулировано.
var todoModel = TodoModel();
console.log(todoModel.todos); //undefined
console.log(todoModel.lastChange) //undefined
todoModel.addToPrivateList(); //taskModel.addToPrivateList
is not a functionэто
это Потерять контекстные проблемы все еще там при использовании класса. Например, это теряет контекст в вложенных функциях. Он не только раздражает во время кодирования, но это также постоянный источник ошибок.
class TodoModel {
constructor(){
this.todos = [];
}
reload(){
setTimeout(function log() {
console.log(this.todos); //undefined
}, 0);
}
}
todoModel.reload(); //undefinedили это Потеря контекст, когда метод используется в качестве обратного вызова, вроде на мероприятии DOM.
$("#btn").click(todoModel.reload); //undefinedНе существует таких проблем при использовании заводской функции, так как она не использует это вообще.
function TodoModel(){
var todos = [];
function reload(){
setTimeout(function log() {
console.log(todos); //[]
}, 0);
}
}
todoModel.reload(); //[]
$("#btn").click(todoModel.reload); //[]Это и стрелка функция
Функция стрелки частично решает это Потери данных контекста в классах, но в то же время создают новую проблему:
этобольше не теряет контекст в вложенных функцияхэтотеряет контекст, когда метод используется в качестве обратного вызова- Функция стрелки способствует использованию анонимных функций
Я изложил Топододол Использование функции стрелки Отказ Важно отметить, что в процессе рефакторинга к функции стрелки мы можем потерять что-то очень важное для читаемости, имя функции. Ищите примеру в:
//using function name to express intent
setTimeout(function renderTodosForReview() {
/* code */
}, 0);
//versus using an anonymous function
setTimeout(() => {
/* code */
}, 0);Откройте для себя функциональный JavaScript был назван одним из Лучшие новые функциональные программирования книги BookAuthority !
Для получения дополнительной информации о применении методов функциональных программиров в реакции посмотрите на Функциональный реагировать Отказ
Учить Функциональный реагировать в проекте, основанном на проекте, с Функциональная архитектура с реагированием и redux Отказ
Следуйте в Twitter