Это мой долг, как преподавателя по программированию, выпускать в мир программистов, мыслящих по-новому. Когда мы переключаемся с императивного на декларативное программирование, мы начинаем мыслить совсем по-другому.
Как только мои студенты заканчивают изучать основы JavaScript, мы переходим к функциональному программированию и методам массивов, которые используются в декларативном стиле программирования. И именно на этом этапе их мозги начинают поджариваться, шипеть и таять словно зефир на костре.
Что такое императивное программирование?
Когда вы были новичком, то, скорее всего, по большей части программировали именно в императивном стиле, то есть вы передавали компьютеру набор команд, которые он должен выполнить, и компьютер выполнял то, что вам нужно, в простой для выполнения последовательности.
Представьте, что у нас есть список паролей, которые чаще всего используются в мире:
const passwords = [
"123456",
"password",
"admin",
"freecodecamp",
"mypassword123",
];
Наше приложение при регистрации будет проверять пароль пользователя и не позволит создать ему пароль, если он есть в этом списке.
Но перед тем, как мы приступим к этому, мы хотим очистить этот список от лишнего. У нас уже есть код, который дает пользователю возможность зарегистрироваться с паролем, длина которого не менее 9 символов. Таким образом, мы можем сократить список, то есть оставить только пароли длиной 9 и более символов, чтобы ускорить проверку.
Применяя императивный стиль программирования, мы бы написали следующее:
// using the passwords constant from above
let longPasswords = [];
for (let i = 0; i < passwords.length; i++) {
const password = passwords[i];
if (password.length >= 9) {
longPasswords.push(password);
}
}
console.log(longPasswords); // logs ["freecodecamp", "mypassword123"];
- Мы создаем пустой список под названием longPasswords.
- Далее мы пишем цикл, который будет выполняться столько раз, сколько паролей в первоначальном списке passwords.
- Затем мы получаем пароль по индексу итерации цикла, на которой мы сейчас находимся.
- После чего мы проверяем, состоит ли пароль из 9 или более символов.
- Если это так, то мы помещаем его в список longPasswords.
Одно из преимуществ императивного программирования заключается в том, что о нем легко рассуждать. Как и компьютер, мы можем следовать шаг за шагом.
Что такое декларативное программирование?
Есть и иной тип мышления в программировании. Вы можете считать, что написание кода - это процесс постоянного определения сущностей. Это называется декларативным программированием.
Императивное и декларативное программирование выполняют одну и ту же задачу. Это лишь разные типы мышления. У них есть свои преимущества и недостатки, и бывают даже ситуации, когда нужно использовать и то, и другое.
Несмотря на то, что новичкам проще рассуждать в стиле императивного программирования, декларативное программирование позволяет нам писать код, который проще воспринимать и который отражает именно то, что мы хотим видеть. Если сюда еще добавить грамотные имена переменных, то это может стать очень мощным инструментом.
Поэтому вместо того, чтобы передавать компьютеру последовательность действий, мы описываем, чего мы хотим, и присваиваем это результату какого-то процесса.
// using the passwords constant from above
const longPasswords = passwords.filter(password => password.length >= 9);
console.log(longPasswords); // logs ["freecodecamp", "mypassword123"];
Список longPasswords определен (или описан) как отфильтрованный список passwords, в котором остались только пароли, длина которых больше или равна 9.
Методы функционального программирования в JavaScript позволяют нам четко описывать то, что нам нужно.
- Это список паролей.
- Это список только длинных паролей. (После выполнения функции filter.)
- Это список паролей с идентификаторами. (После выполнения функции map.)
- Это отдельный пароль. (После выполнения функции find.)
Одно из преимуществ декларативного программирования заключается в том, что оно сначала требует ответить на вопрос, чего мы хотим. И благодаря названиям этих новых сущностей наш код становится более выразительным и наглядным.
И когда наши коллеги-разработчики придут и посмотрят на наш код, им будет проще найти ошибки:
«Вы назвали эту переменную ‘index’, что говорит мне о том, что это число, но я вижу, что это результат работы функции filter, которая возвращает массив. В чем прикол?»
Я хочу подтолкнуть учащихся как можно чаще писать именно декларативный код, постоянно определять (и перепроектировать для переопределения), что из себя представляют сущности.
Вместо того, чтобы держать у себя в голове весь императивный процесс, вы можете запоминать лишь более конкретные и четко определенные вещи.