Как работает этот последний синтаксис? Может ли кто-нибудь разбить его для меня?
Рассмотрим определение switchcase
и switchcaseF
.
const switchcase = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key] : defaultCase
const switchcaseF = cases => defaultCase => key =>
switchcase(cases)(defaultCase)(key)()
Если мы включим применение switchcase
в switchaseF
мы получаем следующее.
const switchcaseF = cases => defaultCase => key =>
(cases.hasOwnProperty(key) ? cases[key] : defaultCase)()
//|____________________________________________________|
// |
// switchcase(cases)(defaultCase)(key)
Кроме того, мы можем переместить приложение функции в условное выражение.
const switchcaseF = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key]() : defaultCase()
Теперь рассмотрим пример из article что вы связались с.
const counter = (state = 0, action) =>
switchcaseF({
'INCREMENT': () => state + 1,
'DECREMENT': () => state - 1
})(() => state)(action.type)
Если мы встроим приложение switchcaseF
в counter
, мы получим следующее.
const counter = (state = 0, action) => {
const cases = {
'INCREMENT': () => state + 1,
'DECREMENT': () => state - 1
}
const defaultCase = () => state
const key = action.type
return cases.hasOwnProperty(key) ? cases[key]() : defaultCase()
}
Следовательно, если action.type
равно 'INCREMENT'
тогда результат state + 1
. Если action.type
равно 'DECREMENT'
, то результат равен state - 1
. В противном случае результат будет state
.
Причина, по которой мы пишем выражения типа () => state + 1
вместо простого state + 1
, заключается в отложенной оценке . Мы оцениваем тело () => state + 1
только при вызове функции. Это предотвращает некорректное поведение, как в следующем примере.
const switchcase = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key] : defaultCase
const never = () => { while (true); }
const example = key => switchcase({
never: never()
})('it works')(key)
console.log(example('it should work')) // expected 'it works' but never returns
Использование switchcaseF
решает эту проблему.
const switchcaseF = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key]() : defaultCase()
const never = () => { while (true); }
const example = key => switchcaseF({
never: () => never()
})(() => 'it works')(key)
console.log(example('it should work')) // 'it works' as expected
Однако учтите, что вы можете использовать геттеры, чтобы он работал и с switchcase
.
const switchcase = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key] : defaultCase
const never = () => { while (true); }
const example = key => switchcase({
get never() { return never(); }
})('it works')(key)
console.log(example('it should work')) // 'it works' as expected
Мы также можем сделать defaultCase
ленивым.
const switchcase2 = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key] : defaultCase.value
const never = () => { while (true); }
const example = key => switchcase2({
get never() { return never(); }
})({ get value() { console.log('yes'); return 'it works'; } })(key)
console.log(example('it should work')) // 'yes' 'it works' as expected
Если вы не хотите, чтобы он был ленивым, вы можете заключить его в strict
следующим образом.
const switchcase2 = cases => defaultCase => key =>
cases.hasOwnProperty(key) ? cases[key] : defaultCase.value
const never = () => { while (true); }
const strict = value => ({ value })
const example = key => switchcase2({
get never() { return never(); }
})(strict('it works'))(key)
console.log(example('it should work')) // 'it works' as expected
Надеюсь, что прояснит ваши сомнения.