Процесс изучения JavaScript обычно начинается с практических занятий. От объявления переменных до понимания ада асинхронного JavaScript, большинство теоретических концепций упущено. И этот пробел начинает раздражать, когда углубляешься в темы.

Имея это в виду, давайте начнем с объяснения некоторых наиболее теоретических (и даже философских) концепций современного JavaScript, начиная с чистоты.

Что это за чистота?

Представьте, что вы создаете сложную систему, используя парадигму функционального программирования. Это означает, что ваш проект будет иметь множество функций, одна из которых вызывает другую, до такой степени, что наступит момент, когда код начнет жить своей собственной жизнью и будет делать то, о чем вы не просили.

Если ваша цель не в том, чтобы создать сумасшедший ИИ, поначалу этого следует избегать. Вы не хотите, чтобы, изменив что-то в одной функции, что-то в другой функции, о которой вы даже не знаете, где она находится, вы бы сделали двойной поворот, не зная, как это было сделано.

Таким образом, чистая функция — это функция, в которой нет изменений. Нечистая функция — это функция, которая изменяет переменные, состояния или данные за пределами своей области.

Философ Гераклит сказал, что нельзя купаться в одной и той же реке дважды, потому что река секунду назад уже не та же самая река сейчас из-за ее течения. Чистые функции идут в обратном направлении и пытаются сохранить одну и ту же реку, чтобы вы могли купаться в ней столько раз, сколько захотите, всегда зная, что произойдет.

Чистые функции

Давайте посмотрим на эту функцию JavaScript:

const calculateDouble = (num) => num * 2;

Здесь у нас есть функция, которая будет вычислять двойное число. Если мы вызовем calculateDouble(4), получим результат 8. Независимо от того, сколько раз мы вызывали эту функцию, мы знаем, что если аргумент равен 4, результат будет равен 8. Если аргумент равен 5, результат будет 10 и так далее.

calculateDouble(4) // returns 8
calculateDouble(4) // returns 8
calculateDouble(4) // returns 8
// the result never changes

Чистая функция будет иметь это неизменное поведение. Это функция, которая знает, кто она. Это как тот старший человек на работе, сверхдисциплинированный и методичный. Все в фирме знают, во сколько она собирается выпить чашку кофе, как отреагирует, когда к ней подойдут, и так далее.

Есть две характеристики:

  1. При одном и том же входе он всегда будет возвращать один и тот же результат.
  2. Никаких побочных эффектов это не произведет.

Нечистые функции

Теперь посмотрите на эту функцию и попытайтесь понять, что она делает:

let num = 8;
const calculateDouble = () => num *= 2;

Эта функция имеет ту же цель, что и предыдущий пример. Но обратите внимание, что он обращается к переменной за пределами своей области. Когда мы вызовем его с calculateDouble(), мы получим результат 16. Если мы вызовем его снова, результат будет 32 и так далее. Здесь мы имеем нечистую функцию.

calculateDouble() // returns 16
calculateDouble() // returns 32
calculateDouble() // returns 64

Другой пример нечистой функции:

const showAlert = () => {
  alert('This is a side effect!');
}

Это также нечистая функция, потому что она имеет побочный эффект. Результат всегда будет одинаковым в зависимости от настроенной вами среды, т. Е. Он всегда будет возвращать предупреждение в окне с одним и тем же сообщением. Однако для создания этого предупреждения требуется доступ к DOM API. В случае с DOM мы уверены, что он, вероятно, никогда не изменится, но если бы это был другой API, кто бы гарантировал нам неизменность?

Другой пример нечистой функции:

const multiplyRandom = (num) => num * Math.random();

Здесь мы берем число и умножаем его на случайное значение (что и делает функция Math.random(). Кстати, тоже нечистая). Даже если ваши аргументы всегда одни и те же, результаты будут разными:

multiplyRandom(3) // returns 1.2427312565643085
multiplyRandom(3) // returns 0.0966362658711748
multiplyRandom(3) // returns 2.493662851387264

Из этих примеров ясно, что нечистая функция на самом деле не знает, что она возвращает. По сравнению с тем стабильным сотрудником, это тот, кто приходит в 8 утра в один день и почти в 12 дня. следующий, и вы не знаете, ответить ли вежливо или сердито. А может быть, это именно творческий сотрудник, который делает что-то потрясающее, если у него есть руководитель, способный использовать его талант.

Поэтому не осуждайте нечистые функции. Избегать всегда хорошо, но они могут быть важны, если вы знаете, где их использовать, тщательно документируя поведение, чтобы код был понятен другим или даже вам в будущем.

Каковы преимущества использования чистых функций?

  • Воспроизводимость: одним из принципов научного эксперимента является возможность его воспроизведения без изменения результата. В программировании эта возможность позволяет легче запускать тесты, не допускать ошибок…
  • Распараллеливание: хотя JavaScript теоретически работает с одним потоком, т. е. одно за другим, асинхронные функции уже довольно распространены. С чистыми функциями вы можете вызывать их параллельно, не опасаясь изменения результата, что экономит время выполнения.
  • Запоминание: в данном случае этот термин означает возможность сохранять в памяти результат выполнения функции. Мы видели, что результат функции всегда будет одним и тем же. Это означает, что мы можем сохранить значение функции в переменной, а затем использовать его вместо функции, и результат будет таким же.

Есть много других преимуществ, особенно когда вы используете функциональное программирование, но для этого нам нужно углубиться в другие концепции, которые будут предметом будущих сообщений.

Заключение

Если у вас есть какие-либо вопросы или вы хотите поделиться какими-либо советами, пожалуйста, оставьте комментарий ниже. Буду рад прочитать ваше мнение и отзывы!

Спасибо за прочтение! Следуйте за мной на этой платформе, чтобы узнать больше о программировании. Хорошего дня, скоро увидимся! 👋

Создавайте приложения с повторно используемыми компонентами, как Lego

Инструмент с открытым исходным кодом Bit помогает более чем 250 000 разработчиков создавать приложения с помощью компонентов.

Превратите любой пользовательский интерфейс, функцию или страницу в компонент многократного использования — и поделитесь им со своими приложениями. Легче сотрудничать и строить быстрее.

Подробнее

Разделите приложения на компоненты, чтобы упростить разработку приложений, и наслаждайтесь наилучшими возможностями для рабочих процессов, которые вы хотите:

Микро-интерфейсы

Система дизайна

Совместное использование кода и повторное использование

Монорепо

Узнать больше