У меня была эта личная мантра: g «Избегайте if..else..else if заявлений и используйте вместо них выражения», если я могу помочь. Это означает, что я могу использовать только троичное выражение, когда дело касается некоторого потока управления.

const decision = val => (if boolean evaluation with val is true)
  ? returnMe 
  : elseReturnMe;

Теперь я ограничен только двумя возможными возвращаемыми значениями или операциями. Зачем мне это делать? Какова цель этой мазохистской мантры?

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

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

Они сделали компьютеры с двоичным кодом. Я почти уверен, что смогу это сделать, по крайней мере, моя уверенность подсказывает мне.

Давайте попробуем это с последовательностью Фибоначчи. Определение, серия чисел, в которой каждое число (число Фибоначчи) является суммой двух предыдущих чисел. Самый простой - это серии 1, 1, 2, 3, 5, 8 и т. Д.

Сначала я реализую это с помощью if..else..else if операторов.

const fibonacci = num => {
 if (num === 0) return 0;
 else if (num === 1) return 1;
 else return fibonacci(num - 1) + fibonacci(num - 2);
}

Я знаю фигурные скобки. Давай, мне лень их печатать. Смирись с этим.

В Haskell это очень просто без if..else. Это выглядит так,

fibonacci :: Integral a => a -> a
fibonacci 0 = 0
fibonacci 1 = 1
fibonacci x = fibonacci(x - 1) + fibonacci(x - 2)

Это потому, что в Haskell есть сопоставление с образцом, а в Javascript этого нет. Это тема для отдельной статьи, просто развлечет ваше любопытство!

Как мне реализовать это в Javascript без сопоставления с образцом и без операторов if..else?

Готовьтесь! Мне придется взломать свой код. Мне понадобятся некоторые функции, которые будут оценивать, равен ли он нулю или единице.

// isZero :: Int -> Bool
const isZero = n => n === 0;
// isOne :: Int -> Bool
const isOne = n => n === 1;

Да, я мог бы объединить эти функции с дизъюнкцией, известной как логическое или. Но теперь у меня есть выбор использовать эти функции вместе или по отдельности.

Затем мне нужна функция, которая вернет ноль или единицу:

// zero :: Int -> Int
const zero = n => isZero(n) ? 0 : n;
// one :: Int -> Int
const one = n => isOne(n) ? 1 : n;

Похоже, я все дальше ухожу от простого решения, потому что пишу все эти функции. Что, если я смогу их совместить? Позвольте мне сделать or функцию. Пун входящий, дисфункция!

// or :: (a -> b) -> (a -> b) -> a -> b
const or = (f, g) => x =>
  f(x) || g(x);

Как мне это использовать? Позвольте мне использовать его с функциями zero и one.

// zeroOrOne :: Int -> Int
const zeroOrOne = or(zero, one);

Посмотрим, смогу ли я уже построить с его помощью функцию Фибоначчи без if..else операторов.

// fibonacci :: Int -> Int
const fibonacci = n => n === 0 || n === 1
  ? zeroOrOne(n)
  : fibonacci(n - 1) + fibonacci(n - 2);
const result = fibonacci(6);
console.log(result) // 8 

Оно работает! но подождите ... Думаю, я все еще могу провести рефакторинг своей логической оценки. У меня есть эти маленькие функции выше, я думаю, что могу объединить их с or

// isZeroOrOne :: Int -> Bool
const isZeroOrOne = or(isZero, isOne);

Ну наконец то,

const fibonacci = n => isZeroOrOne(n)
  ? zeroOrOne(n)
  : fibonacci(n - 1) + fibonacci(n - 2);

Никаких фактических if..else операторов в этой статье не использовалось.

P.S. Я выбрал фотографию выше, потому что думал, что она связана с рекурсией.