[英]Can someone explain this higher-order JavaScript function confusing syntax?
I am reading the book "Eloquent JavaScript".我正在阅读“Eloquent JavaScript”这本书。
In Chapter 5 he describes a particular higher-order function.在第 5 章中,他描述了一个特定的高阶函数。 It is called noisy()
it is printed below...它被称为noisy()
它打印在下面......
function noisy(f) {
return (...args) => {
console.log("calling with", args);
let result = f(...args);
console.log("called with", args, ", returned", result);
return result;
};
}
Here is the part that is confusing me.这是让我困惑的部分。 He calls the function noisy
as follows...他调用函数noisy
如下...
noisy(Math.min)(3,2,1);
I do not understand why the function is called that way.我不明白为什么以这种方式调用该函数。 Why isn't it called like this...为什么不叫这个...
noisy(Math.Min(3,2,1))
Edit: I see now what is going on.编辑:我现在明白发生了什么。 It was explained by Simone below.下面由 Simone 解释。
noisy(Math.min)(3,2,1) is equivalent to (noisy(Math.min))(3,2,1).
If you try to get the type of noisy
, you'll get:如果您尝试获得noisy
类型,您将获得:
typeof noisy
>> "function"
Same thing if you ask for the type of noisy(Math.min)
:如果您要求noisy(Math.min)
类型noisy(Math.min)
同样的事情:
typeof noisy(Math.min)
>> "function"
If you want you can also store this function into a variable:如果需要,您还可以将此函数存储到变量中:
const noisyFunction = noisy(Math.min)
So that you can call it like a regular function:这样你就可以像普通函数一样调用它:
noisyFunction(1,2,3)
noisy(Math.min)(3,2,1)
is exactly the same, just written in a different, shorter way. noisy(Math.min)(3,2,1)
完全相同,只是以不同的、更短的方式编写。 The main point is, a higher-order function is just a function that returns a function.重点是,高阶函数只是一个返回函数的函数。
noisy
takes a function as a parameter, and returns a function. noisy
将函数作为参数,并返回一个函数。 The thing you pass it is expected to be a function.你传递的东西应该是一个函数。 We can see that in this line here:我们可以在这里看到这一行:
let result = f(...args);
f
is the parameter. f
是参数。 That line of code using it as a function.将其用作函数的那行代码。
noisy
gives you a function back. noisy
给你一个功能回来。 We can see that here in the code:我们可以在代码中看到:
return (...args) => {返回(...参数)=> {
The important thing is that a function is not the same as the value returned by a call to the function.重要的是,函数与调用函数返回的值不同。 Math.min
is a function, a thing. Math.min
是一个函数,一个东西。 Math.min(1, 2, 3)
is a call to a function , an action -- which returns a number. Math.min(1, 2, 3)
是对函数的调用,是一个动作——它返回一个数字。 When you put the parentheses on Math.min
, that tells the compiler you want to execute Math.min
.当您将括号放在Math.min
,它告诉编译器您要执行Math.min
。
Math.min(1, 2, 3)
doesn't return a function, it returns a number. Math.min(1, 2, 3)
不返回函数,它返回一个数字。 The code you were given isn't passing that parameter list to Math.min
;您给出的代码没有将该参数列表传递给Math.min
; it's passing that parameter list to a completely different function, the one returned by noisy
.它正在将该参数列表传递给一个完全不同的函数,即由noisy
返回的函数。
This becomes more clear if we assign the values to local variables:如果我们将值分配给局部变量,这将变得更加清晰:
// 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);
If we break down your version of the call, noisy(Math.Min(3,2,1))
, we get this:如果我们分解你的电话版本, 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);
Look inside noisy
.看看里面noisy
。 It returns a function which includes the following line:它返回一个包含以下行的函数:
let result = f(...args);
So, in your version, y
is the function that noisy
returns.因此,在您的版本中, y
是noisy
返回的函数。 It's never executed, but if it were, it would be trying to treat the integer value 1
as a function.它永远不会执行,但如果是,它会尝试将整数值1
视为函数。 But an integer is not a function.但是整数不是函数。
noisy(Math.min)
returns a function (see the return statement: return (...args) => { ... }
). noisy(Math.min)
返回一个函数(参见 return 语句: return (...args) => { ... }
)。
noisy(Math.min)(3,2,1);
just immediately calls that function.只是立即调用该函数。
You could also first assign the function to a variable and then call it like this:您也可以先将函数分配给一个变量,然后像这样调用它:
let fnct = noisy(Math.min);
fnct(3,2,1);
You cannot call it like noisy(Math.Min(3,2,1))
as Math.min(3,2,1)
returns a number but noisy
expects a function reference to be passed (hence Math.min
- note its missing the ()
as it's passing a reference to that function rather than the result of its execution).你不能把它像noisy(Math.Min(3,2,1))
作为Math.min(3,2,1)
返回一个数字,但noisy
希望传递(因此函数引用Math.min
-记下它的缺失()
因为它正在传递对该函数的引用而不是其执行结果)。
Your call would break in line 4, ie:您的呼叫将在第 4 行中断,即:
let result = f(...args);
as f
is not a function in your case but rather the result of Math.min(3,2,1) // = 1
.因为f
在您的情况下不是函数,而是Math.min(3,2,1) // = 1
。
noisy
returns a function that uses the parameter f
as a callback function. noisy
返回一个使用参数f
作为回调函数的函数。
Here is an es5 version of the code (which needs a little more code to maintain functionality) to help you understand:下面是一个 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));
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.