繁体   English   中英

雄辩的JavaScript,第二版,第5章高阶函数

[英]Eloquent JavaScript, 2nd Edition, Chapter 5 Higher-Order Functions

我是JavaScript的新手,我希望在第二版的第5章中获得一些帮助。 雄辩的JavaScript。 具体来说,我遇到了以下示例:

function noisy(f) {
  return function(arg) {
    console.log("calling with", arg);
    var val = f(arg);
    console.log("called with", arg, "- got", val);
    return val;
  };
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false

我想我理解生成其他函数的高阶函数的概念,但是不确定我是否理解“捕获”的概念以及它在这里的含义。 具体来说, var val = f(arg);

有人可以引导我浏览该行代码吗? 您如何将一个参数传递给另一个参数? 我不确定我是否使用了正确的术语,所以如果我记错了,请原谅。 我只是不明白那条线,无法轻易找到与此主题相关的其他主题。

谢谢!

noisy是一个函数,它引用另一个函数f并返回一个包装f的新函数,以便将其调用和返回值记录到控制台。

val是调用函数f的结果,其中f是调用noisy时传递的函数引用。

要逐步进行:

// noisy accepts argument f (where f itself appears to be a function)
function noisy(f) {
    // noisy returns a new function that takes an argument arg
    return function(arg) {
        // when this new function is called, it logs to console
        console.log("calling with", arg);
        // the function you originally passed to noisy is now called, with the return value stored in val
        var val = f(arg);
        // return value val also logged to console
        console.log("called with", arg, "- got", val);
        // return value val is returned from the generated function
        return val;
    };
}
// noisy is called with the inbuilt function Boolean and the argument 0 (to test the boolean value of 0)
noisy(Boolean)(0);

另一个用例可能是这样的:

function someFuncToMonitor(someArg) {
    return someArg + 1;
}
monitoredFunc = noisy(someFuncToMonitor);
result = monitoredFunc(5);
// calling with 5
// calling with 5 - got 6

因此,在短期呼叫monitoredFunc调用你的someFuncToMonitor功能为你,并告诉你关于呼叫和结果。

有问题的代码:

function noisy(f) {
  return function(arg) {
    console.log("calling with", arg);
    var val = f(arg);
    console.log("called with", arg, "- got", val);
    return val;
  };
}
noisy(Boolean)(0);
// → calling with 0
// → called with 0 - got false

发生了什么(类似于通过JavaScript进行的“神奇的校车”之旅):

  1. 直到代码行noisy(Boolean)(0);才实际执行任何操作noisy(Boolean)(0);
  2. 到达此行时,首先使用JavaScript内置函数Boolean作为其参数f调用noisy函数。
  3. 返回一个匿名函数:
    • 运行时,匿名函数会收到一个称为arg的新参数。
    • 然后匿名函数将记录字符串“ calling with”,后跟arg
    • 然后匿名函数将调用函数f (已通过闭包在匿名函数中进行了记忆)并将返回值存储在变量val
    • 然后匿名函数将记录字符串“ with with”,后跟arg ,后跟字符串“ -get”,后跟val
    • 最后,匿名函数还将返回变量val的值。
  4. 如上所述, noisy(Boolean)的返回值是匿名函数, Boolean在刚刚生成的该匿名函数中扮演f的角色。
  5. 剩余的(0)现在用于以参数arg 0调用此新生成的匿名函数。
  6. 遵循上面3.中描述的五个子步骤,结果是:
    • 没有可见的输出,但是arg的值为0作为匿名函数调用的第一步。
    • 匿名函数记录字符串“用0呼叫”
    • Boolean函数使用参数0运行,该参数返回false ,并将其存储到val
    • 匿名函数记录字符串“用0调用-得到假”
    • 匿名函数返回false (但是示例代码未以任何方式使用或存储此值)。

现在,让我们看一下实际的代码行,并将其与上述步骤匹配:

  1. 此代码开始执行: noisy(Boolean)
  2. 执行noisy的以下代码,将Boolean参数传递给noisy并存储到变量f

     return function(arg) { console.log("calling with", arg); var val = f(arg); console.log("called with", arg, "- got", val); return val; }; 
  3. 此代码的noisy(Boolean)部分noisy(Boolean)(0); 现在已替换为步骤2中显示的返回值。
  4. 因此,现在noisy(Boolean)(0)实际上已成为[[anonymous function]](0)
  5. 现在执行此替换“代码” [[anonymous function]](0)
  6. 结果,将执行以下代码行:

      console.log("calling with", 0); // because 0 was passed in for arg var val = Boolean(0); // because Boolean is stored in f console.log("called with", 0, "- got", false); // because the Boolean value of 0 is false 

噪声函数采用单个参数f ,该参数为函数。 当您调用noisy时,它将返回一个新函数(这意味着noisy(Boolean)返回一个函数)。 之所以进行捕获是因为新函数可以访问任何嘈杂的参数,包括f参数(程序员将此概念称为闭包)。 当您有noisy(Boolean)(1) ,内部函数中的f引用Boolean 因此,由于var val = f(arg) ,所以val设置为Boolean(1) var val = f(arg)

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM