有人能解释一下这个高阶JavaScript函数的混乱语法吗?

5

我正在阅读《JavaScript编程精解》这本书。

在第五章中,作者描述了一种特殊的高阶函数。它被称为noisy(),如下所示...

function noisy(f) {
  return (...args) => {
   console.log("calling with", args);
   let result = f(...args);
   console.log("called with", args, ", returned", result);
   return result;
 };
}

这里让我感到困惑的部分是,他按以下方式调用函数noisy...

noisy(Math.min)(3,2,1);

我不理解为什么这个函数被称为那样。为什么不叫做这个...

noisy(Math.Min(3,2,1))

编辑:我现在明白了发生了什么。Simone已经解释了。

noisy(Math.min)(3,2,1) is equivalent to (noisy(Math.min))(3,2,1).

noisy 接受一个函数并返回一个调用传递函数的函数。 - pishpish
我认为 noisy 的目的是在调用传递给它的函数 (f) 时制造一些(嗯...)噪音。因此,在调用 noisy(Math.min) 后,您将获得一个函数,然后使用 (3,2,1) 参数调用该函数。本质上,这是为了在实际调用 f 之前和之后记录到控制台而装饰(或“代理”)对 f 的调用。 - haim770
1
可能是什么是'柯里化'?的重复问题。 - Etheryte
3个回答

2

如果您尝试获取 noisy 的类型,您将得到:

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)与其他写法完全相同,只是以不同的更短的方式书写。关键在于,高阶函数只是返回一个函数的函数。


好的,我明白了。它可以这样写:(noisy(Math.min))(3,2,1) ()运算符的优先级导致它被执行的方式就像我所写的一样? - root44
是的,正确,但如果像您第二个示例中那样编写,它将无法工作,因为它们不等价。noisy(Math.min(3,2,1))是一个常规函数调用,其中Math.min(3,2,1)是第一个且唯一的参数。 - Simone
是的,我现在明白了。谢谢。 - root44
非常感谢您发布这个问题。我也有完全相同的疑问! - adm-gis

0

noisy(Math.min) 返回一个函数(请参见返回语句: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 的结果。


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));


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接