我正在阅读“Eloquent Javascrip”一书。
在第5章中,他描述了一个特定的高阶函数。它被称为嘈杂()它打印在下面......
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);
我不明白为什么以这种方式调用函数。为什么不这样称呼......
noisy(Math.Min(3,2,1))
编辑:我现在看到发生了什么。以下是Simmone的解释。
noisy(Math.min)(3,2,1) is equivalent to (noisy(Math.min))(3,2,1).
答案 0 :(得分:1)
如果您尝试获取typeof noisy
>> "function"
的类型,您将获得:
noisy(Math.min)
如果您要求typeof noisy(Math.min)
>> "function"
的类型:
const noisyFunction = noisy(Math.min)
如果需要,您还可以将此功能存储到变量中:
noisyFunction(1,2,3)
这样你就可以像普通函数一样调用它:
noisy(Math.min)(3,2,1)
{{1}}完全相同,只是以不同的,更短的方式编写。重点是,高阶函数只是一个返回函数的函数。
答案 1 :(得分:0)
noisy
将函数作为参数,并返回一个函数。你传递它的东西应该是一个功能。我们可以在这一行中看到:
let result = f(...args);
f
是参数。那行代码使用它作为函数。
noisy
为您提供功能。我们可以在代码中看到:
return(... args)=> {
重要的是,函数与调用返回给函数的值不同。 Math.min
是一种功能,一种东西。 Math.min(1, 2, 3)
是对函数的调用,一个返回数字的操作。当您将括号放在Math.min
上时,它告诉编译器您要执行 Math.min
。
Math.min(1, 2, 3)
不返回函数,它返回一个数字。您获得的代码未将该参数列表传递给Math.min
;它将该参数列表传递给完全不同的函数,即noisy
返回的函数。
如果我们将值分配给局部变量,那就更清楚了:
// x is a function, not a number.
var x = Math.min;
// y is a function: noisy returns a function.
var y = noisy(x);
// Call the function noisy returned:
var z = y(1, 2, 3);
如果我们分解您的通话版本noisy(Math.Min(3,2,1))
,我们就会知道:
// Set x equal to the integer value 1
var x = Math.min(3, 2, 1);
var y = noisy(x);
查看noisy
内部。它返回一个包含以下行的函数:
let result = f(...args);
因此,在您的版本中,y
是noisy
返回的函数。它永远不会执行,但如果是,它会尝试将整数值1
视为一个函数。但是整数不是函数。
答案 2 :(得分:0)
noisy(Math.min)
返回一个函数(参见return语句:return (...args) => { ... }
)。
noisy(Math.min)(3,2,1);
只是立即调用该函数。
您也可以先将函数分配给变量,然后调用它:
let fnct = noisy(Math.min);
fnct(3,2,1);
你不能像noisy(Math.Min(3,2,1))
那样称呼它
当Math.min(3,2,1)
返回一个数字,但noisy
期望传递一个函数引用(因此Math.min
- 请注意它错过了()
,因为它传递了对该引用的引用功能而不是执行的结果。)
你的电话将在第4行中断,即:
let result = f(...args);
因为f
不是您的案例中的函数,而是Math.min(3,2,1) // = 1
的结果。
答案 3 :(得分:0)
noisy
返回一个使用参数f
作为回调函数的函数。
以下是代码的es5版本(需要更多代码来维护功能)以帮助您理解:
function noisy(f) {
return function () {
var args = [];
for (var _i = 0; _i < arguments.length; _i++) {
args[_i] = arguments[_i];
}
console.log("calling with", args);
var result = f.apply(void 0, args);
console.log("called with", args, ", returned", result);
return result;
};
}
//test
console.log(noisy(Math.min)(3, 2, 1));