摘自《 Eloquent Javascript第三版》第5章。我似乎在研究中找不到此构造'f()()',我想了解更多有关它的信息。
我希望能够使用
noisy(Math.min(3, 2, 1));
但是这样做时没有输出。但是,本书示例可以按预期工作。但是如何?
书籍示例:
function noisy(f) {
return (...args) => {
console.log('calling with', args);
let result = f(...args);
console.log('called with', args + ', returned', result);
return result;
};
}
noisy(Math.min)(3, 2, 1);
f()()
调用一个名为f
的函数,该函数可能会返回一个函数-然后,最后的()
会调用该返回的函数。例如
const f = () => {
console.log('first invoke');
return () => console.log('second invoke');
};
const returnedFn = f();
console.log('----');
returnedFn();
[f()()
与上面类似,不同之处在于它不将returnedFn
存储在变量中-而是立即执行returnedFn
。
这与noisy
所做的事情相同-它返回一个函数,因此,如果要立即调用返回的函数而不在任何地方存储返回的函数,请在调用()
之后放置另一个noisy
。
问题所在
noisy(Math.min(3, 2, 1))
是它立即调用Math.min
-解释器将其简化为
noisy(1)
在调用noisy
之前,因此noisy
看不到有关Math.min
或调用它的参数的任何信息。 (但是noisy
函数的全部要点是记录函数的输入和输出)
noisy()
接受一个函数作为参数(通过let result = f(...args);
行显而易见)。 Math.min(3, 2, 1)
解析为一个值,而不是函数,因此它传递给noisy()
时不起作用。
f()()
的全部含义是函数f
返回一个函数,然后该函数本身将被执行。如果这样分解,可能会更容易理解:
let g = f();
let result = g();
noisy
接受一个函数作为参数,并返回一个。每当尝试noisy(Math.min(3, 2, 1));
时,都会将Math.min(3, 2, 1)
的结果传递给嘈杂的声音,这与调用noisy(1)
相同。
您还可以将混乱的说明分成两部分:
let noisyMin = noisy(Math.min);
noisyMin(3, 2, 1);
基本上,您只得到noisy(Math.min)
的函数,然后立即调用它。
[f()()
仅在f()
返回函数时才可能。