Один из самых любимых вопросов в интервью по JavaScript — «Чистые и нечистые функции». В Интернете доступно гораздо больше информации о функциональном программировании, и, вероятно, каждый разработчик знает, что такое чистая функция. Но возникают вопросы, зачем это нужно и действительно ли у нас есть практический пример этого.
Я хотел бы определить чистую функцию как функцию, не имеющую внутреннего состояния. Это означает, что все операции, которые он выполняет, не зависят от этого состояния, имеют одни и те же входные параметры и производят один и тот же детерминированный вывод.
/ Pure Function const sumPure = (a, b) => { return a + b; };
После вызова чистой функции он выдает результат ниже, что означает, что для каждого вызова функции он выдает одинаковый вывод.
sumPure(1, 1); // OutPut: 2 sumPure(1, 1); // OutPut: 2 sumPure(1, 1); // OutPut: 2
С другой стороны, функция Impure выдает разные выходные данные для каждого вызова функции.
// Impure Function const sumImpure = (() => { let state = 0 return (v) => { return state += v } })(); sumImpure(1) // OutPut: 1 sumImpure(1) // OutPut: 2 sumImpure(1) // OutPut: 3
Ключевым выводом здесь является то, что даже если входные данные не меняются, нечистая функция может давать другой результат.
Чистая функция:
- Может использоваться во многих экземплярах, не влияя на результаты вывода.
class Calculator { constructor(addFn) { this.addFn = addFn; } add(a, b) { return this.addFn(a, b); } } const c1 = new Calculator(add); const c2 = new Calculator(add); c1.add(1, 1); // OutPut: 2 c2.add(1, 1); // OutPut: 2
Вывод: если функция чистая и не имеет состояния, ее можно безопасно использовать совместно со многими экземплярами классов Calculator:
Нечистая функция:
- Невозможно поделиться, потому что на внутреннее состояние можно повлиять извне.
const add = (() => { let state = 0; return (v) => { return state += v; } })(); class Calculator { constructor(addFn) { this.addFn = addFn; } add(a, b) { return (this.addFn(a), this.addFn(b)); } } const c1 = new Calculator(add); const c2 = new Calculator(add); c1.add(1, 1); // 2 c2.add(1, 1); // 4 <------ here we have `4` instead of `2`
Вывод: функция, которая не является чистой, не может использоваться совместно. Это связано с тем, что операции, выполняемые одним экземпляром калькулятора, будут влиять на состояние функции и, следовательно, на результат операций, выполняемых другим экземпляром калькулятора.