如果没有参数传递给第一个返回的函数,组合函数的 reduce 函数的初始值是多少?



我曾试图重写compose函数,以使用不同的参数打印到控制台,但我仍然无法解决。compose函数第一次调用arg是未定义的。因此,reduce函数将使用数组的第一个元素(console.clear(((作为初始值,并将其用作下一个函数getCurrentTime的参数。

当使用convertToCivilianTime调用compose时,它使用serializeClockTime的返回值作为compose中第一个返回函数的参数。

那么,如何在第一次使用未定义的arg参数调用compose而不引起错误呢?

const compose = (...fns) =>
(arg) =>
fns.reduce( (composed, f) => f(composed), arg)
const oneSecond = () => 1000
const getCurrentTime = () => new Date()
const clear = () => console.clear()
const log = message => console.log(message)
const serializeClockTime = date => ({
hours: date.getHours(),
minutes: date.getMinutes(),
seconds: date.getSeconds()
})
const civilianHours = clockTime => ({
...clockTime,
hours: ( clockTime.hours > 12 ) ? clockTime.hours - 12 : clockTime.hours
})
const appendAMPM = clockTime => ({
...clockTime,
ampm: ( clockTime.hours >= 12 ) ? "PM" : "AM"
})
const display = target => time => target(time)
const formatClock = format => time => format.replace('hh', time.hours).replace('mm', time.minutes).replace('ss', time.seconds).replace('tt', time.ampm)
const prependZero = key => clockTime => ({
...clockTime,
[key] : ( clockTime[key] < 10 ) ? "0" + clockTime[key] : clockTime[key]
})
const convertToCivilianTime = clockTime => compose(appendAMPM, civilianHours)(clockTime)
const doubleDigits = civilianTime => compose(
prependZero('hours'),
prependZero('minutes'),
prependZero('seconds')
)(civilianTime)
const startTicking = () => setInterval(compose(
clear,
getCurrentTime,
serializeClockTime,
convertToCivilianTime,
doubleDigits,
formatClock('hh:mm:ss tt'),
display(log)
),
oneSecond()
)
startTicking()

undefined作为初始参数传递给reduce并不意味着"使用默认初始参数"(数组的第一个元素(,而只是"使用undefined作为初始参数":

const arr = [1, 2, 3];
const traceSum = (a, b) => {
console.log(a, b)
return a + b
};
console.log("reduce without initial argument:",        arr.reduce(traceSum));
console.log("reduce with initial argument:",           arr.reduce(traceSum, 0));
console.log("reduce with initial argument undefined:", arr.reduce(traceSum, undefined));

因此,调用由compose创建的函数是安全的,即使您没有提供参数,因为arg将只是一个显式undefined,因此每个函数都会被执行,但经过它们的初始值是undefined:

const compose = (...fns) =>
(arg) =>
fns.reduce( (composed, f) => f(composed), arg)

const trace = message => value => {
console.log(message, value);
return value;
}
const test = compose(trace("one"), trace("two"));
console.log(test("hello"));
console.log(test());

你只需要确保你的组合函数可以在没有初始值的情况下工作:

const compose = (...fns) =>
(arg) =>
fns.reduce( (composed, f) => f(composed), arg)
const excited = str => str + "!";
const loud = str => str.toUpperCase();
const greet = () => "hey";
const shout = compose(loud, excited);
const shoutGreeting = compose(greet, shout);
console.log(shout("stop"));                //works with initial value
console.log(shoutGreeting());              //works without initial value
console.log(shoutGreeting("hammer time")); //ignores initial value
console.log(shout());                      //error - initial value expected

当没有参数作为reduce函数的initialValue传递时,它将第一次用数组的前两个元素调用回调。

例如:

[1, 2, 3, 4, 5].reduce((a, b) => {
console.log(a, ',', b, ',', a + b)
return a + b;
}

它将导致以下日志:

1 , 2 , 3
3 , 3 , 6
6 , 4 , 10
10 , 5 , 15

相关内容

最新更新