Вот и получается, что нужно городить IIFE (immediately invoked function expression), потому что это единственный способ инкапсулировать вычисление и вернуть результат, что, согласитесь, совсем не удобно и не бесплатно (хотя конечно умный компилятор это оптимизирует, но не все языки компилируемые)
Не понимаю, почему авторы новых языков не делают их «expression oriented», то есть чтобы все эти if, for, {} возвращали значение, и можно было помечать «переменные» как неизменяемые. Без этого при условной инициализации приходится сначала объявить неинициализированную неконстантную переменную, а потом присвоить ей соответствующее значение в каждой ветке условного оператора. Что при дальнейшем рефакторинге обязательно выльется в ее использование до инициализации. А вот если бы он (if) возвращал значение, можно было бы написать const foo = if (a > 10) { 10 } else { 20 }
В частности для этого подозреваю был придуман тернарный оператор. Особенно это удобно когда для инициализации нужно вычислить ряд промежуточных значений, можно ввести скоуп с помощью {} и вернуть из него одно значение, не замусоривая функцию лишними переменными и четко обозначая, что после определенной точки они не нужны. Ну и из цикла бывает удобно на нужной итерации выйти со значением.
const foo = if (a > 10) { 10 } else { 20 }
В частности для этого подозреваю был придуман тернарный оператор. Особенно это удобно когда для инициализации нужно вычислить ряд промежуточных значений, можно ввести скоуп с помощью {} и вернуть из него одно значение, не замусоривая функцию лишними переменными и четко обозначая, что после определенной точки они не нужны. Ну и из цикла бывает удобно на нужной итерации выйти со значением.
Все-таки какой-то не совсем динамически типизированный