Нам часто пишут о том, что сложно понять, в каком порядке выполняется код и как, в целом, происходит процесс вычисления. Например:
Здравствуйте! Сначала прошел задание, а затем у меня появился вопрос. Проверка strings.toUpperCase(char) === char сначала переводит символ в верхний регистр, а потом сравнивает с ним же? Или происходит просто проверка без перевода? По логике кода происходит второй вариант, но все же хочу уточнить, т.к. согласно учебнику — .toUpperCase() именно переводит в верхний регистр.
Этот вопрос глубже, чем кажется на первый взгляд. Существуют теоретические модели, описывающие то, как происходят вычисления. Необходимо сразу оговориться — слово «модель» означает, что мы моделируем поведение системы таким образом, чтобы акцентировать внимание на тех свойствах системы, которые изучаются, но сама модель не отражает того, как на самом деле реализован предмет моделирования.
Здесь мы рассмотрим самую простую и понятную модель, которая называется подстановочная модель вычислений
. Главное условие, которое должно соблюдаться для возможности ее применения — отсутствие изменяемого состояния. Если в нашей программе есть хоть одно изменение состояния (первое присваивание не является изменением состояния), то эта модель не работает: в этом можно убедиться, если попытаться ее применить. Под изменением состояния мы понимаем модификацию переменных и составных структур, которые лежат в этих переменных. Отсюда следует, что при использовании подстановочной модели все переменные рассматриваются как константы.
Подписывайтесь на канал Кирилла Мокевнина в Telegram — чтобы узнать больше о программировании и профессиональном пути разработчика
Суть модели заключается в том, что при вычислении выражений происходит подстановка значений констант на месте их идентификаторов. Этот процесс продолжается до полного раскрытия. В конце, когда останутся только конкретные значения и базовые операции, происходит так называемая редукция — процесс вычисления операций.
Рассмотрим следующий код:
const pi = () => {
return 3.14;
}
const multi = (a, b) => {
return Math.round(a * a + b * b);
}
multi(pi(), 4);
Попробуем вычислить результат выражения multi(pi(), 4)
, используя подстановочную модель вычислений.
multi(pi(), 4);
// Подстановка `pi`
multi(3.14, 4)
// Подстановка `multi`
Math.round(3.14 * 3.14 + 4 * 4);
// Редукции
Math.round(9.8596 + 4 * 4);
Math.round(9.8596 + 16);
Math.round(25.8596);
// Подстановки внутри `round` и вычисления мы не видим,
// потому что это встроенная функция
26;
Как видите — все достаточно просто. Теперь должно быть понятно, каким образом, используя подстановочную модель, разобрать пример, который был в начале статьи.
Читайте также: Что такое ссылочная прозрачность и как она влияет на эффективность программиста.