有人能解释一下这个高阶JavaScript函数混乱的语法吗?
我正在读《雄辩的JavaScript》一书 在第5章中,他描述了一个特殊的高阶函数。它被称为有人能解释一下这个高阶JavaScript函数混乱的语法吗?,javascript,Javascript,我正在读《雄辩的JavaScript》一书 在第5章中,他描述了一个特殊的高阶函数。它被称为noised()它被打印在下面 function noisy(f) { return (...args) => { console.log("calling with", args); let result = f(...args); console.log("called with", args, ", returned&qu
noised()
它被打印在下面
function noisy(f) {
return (...args) => {
console.log("calling with", args);
let result = f(...args);
console.log("called with", args, ", returned", result);
return result;
};
}
这是让我困惑的部分。他调用函数noised
,如下所示
noisy(Math.min)(3,2,1);
我不明白为什么这个函数被这样调用。为什么不这样叫
noisy(Math.Min(3,2,1))
编辑:我现在知道发生了什么。下面是西蒙的解释
noisy(Math.min)(3,2,1) is equivalent to (noisy(Math.min))(3,2,1).
Noised
将函数作为参数,并返回函数。你传递给它的东西应该是一个函数。我们可以在这行中看到:
let result = f(...args);
f
是参数。将其用作函数的代码行
noised
返回一个函数。我们可以在代码中看到:
返回(…参数)=>{
重要的是函数与调用函数返回的值不同。Math.min
是一个函数,一个东西。Math.min(1,2,3)
是对函数的调用,是一个操作,返回一个数字。当您在Math.min
上加括号时,它告诉编译器您要执行Math.min
Math.min(1,2,3)
不返回函数,它返回一个数字。给定的代码没有将该参数列表传递给Math.min
;而是将该参数列表传递给一个完全不同的函数,noised
返回的函数
如果我们将值分配给局部变量,这一点就更加清楚了:
// 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);
如果我们对您的调用版本进行分解,noised(Math.Min(3,2,1))
,我们会得到以下结果:
// Set x equal to the integer value 1
var x = Math.min(3, 2, 1);
var y = noisy(x);
查看内部noised
。它返回一个包含以下行的函数:
let result = f(...args);
因此,在您的版本中,y
是noised
返回的函数。它从未执行过,但如果执行过,它将尝试将整数值1
视为函数。但整数不是函数。noised(Math.min)
返回函数(请参阅返回语句:return(…args)=>{…}
)
noised(Math.min)(3,2,1);
立即调用该函数
您也可以先将函数分配给变量,然后按如下方式调用它:
let fnct = noisy(Math.min);
fnct(3,2,1);
您不能像
嘈杂(Math.Min(3,2,1))
asMath.min(3,2,1)
返回一个数字,但noised
期望传递一个函数引用(因此Math.min
-注意它缺少()
,因为它传递的是对该函数的引用,而不是执行结果)
您的呼叫将在第4行中断,即:
let result = f(...args);
由于
f
在您的情况下不是一个函数,而是Math.min(3,2,1)/=1
的结果,如果您尝试获取噪声的类型,您将得到:
typeof noisy
>> "function"
如果您询问噪音的类型(Math.min)
,也是一样的:
如果需要,还可以将此函数存储到变量中:
const noisyFunction = noisy(Math.min)
这样您就可以像调用常规函数一样调用它:
noisyFunction(1,2,3)
noised(Math.min)(3,2,1)
完全相同,只是用不同的、更短的方式编写。要点是,高阶函数只是一个返回函数的函数。noised
返回一个使用参数f
作为回调函数的函数
以下是es5版本的代码(需要更多的代码来维护功能),以帮助您理解:
功能噪音(f){
返回函数(){
var args=[];
对于(var_i=0;_i console.log(noised(Math.min)(3,2,1));
noised
接受一个函数并返回一个调用传递函数的函数。我假设noised
的目的是在调用传递给它的函数(f
)时发出一些(嗯…)噪音。因此,在调用noised(Math.min)之后
返回一个函数,然后使用(3,2,1)
参数调用该函数。本质上,修饰(或“代理”)对f
的调用,以便在实际调用f
前后记录到控制台。我得到了可能重复的Ok。它可能是这样写的(noise(Math.min))(3,2,1)()运算符的优先级导致它像我写的那样执行?是的,正确,但如果像在第二个示例中那样编写,它将不起作用,因为它们不等效。noised(Math.min(3,2,1))
是一个常规函数调用,其中Math.min(3,2,1)
是第一个也是唯一的论点。是的,我现在明白了。谢谢。非常感谢你发布这篇文章。我有完全相同的问题!
noisyFunction(1,2,3)