Eloquent JavaScript,第2版,第5章高阶函数

时间:2015-01-14 02:33:53

标签: javascript

我是JavaScript的新手,我希望在第二版中获得第5章的帮助。 Eloquent 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);

有人可以带我走过那行代码吗?你如何将论证传递给另一个论点?我不确定我是否使用了正确的术语,所以如果我弄错了,请原谅。我只是不理解这条线,并且不能轻易找到关于这个主题的任何其他线索。

谢谢!

3 个答案:

答案 0 :(得分:3)

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功能并告诉您有关呼叫和结果的信息。

答案 1 :(得分:2)

有问题的代码:

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);
  2. 之前,实际上没有执行任何操作
  3. 当达到此行时,首先调用noisy函数,并使用JavaScript内置函数Boolean作为其参数f
  4. 返回匿名函数:
    • 运行时,匿名函数会收到一个名为arg的新参数。
    • 然后匿名函数将记录字符串“calling with”,后跟arg
    • 然后匿名函数将调用函数f(已通过闭包在匿名函数中记忆)并将返回值存储在变量val中。
    • 然后匿名函数将记录字符串“call with”后跟arg,后跟字符串“ - got”,然后是val
    • 最后,匿名函数也将返回变量val中的值。
  5. noisy(Boolean)的返回值是如上所述的匿名函数,Boolean在刚刚生成的匿名函数中扮演f角色。
  6. 剩下的(0)现用于调用这个新生成的匿名函数,参数arg为0。
  7. 遵循上述3.中描述的五个子步骤,导致:
    • 没有可见的输出,但arg取值为0作为匿名函数调用的初始步骤。
    • 匿名函数记录字符串“call with 0”
    • Boolean函数运行时参数为0,返回false,存储到val
    • 匿名函数记录字符串“call with 0 - got false”
    • 匿名函数返回false(但示例代码不以任何方式使用或存储此值。)
  8. 现在让我们看看实际的代码行,并将它们与上述步骤匹配:

    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)的{​​{1}}部分现已替换为步骤2中显示的返回值。
    4. 现在,行noisy(Boolean)(0);实际上已成为noisy(Boolean)(0)
    5. 此替换“代码”[[anonymous function]](0)现已执行。
    6. 结果,执行以下代码行:

      [[anonymous function]](0)

答案 2 :(得分:0)

嘈杂函数采用单个参数f这是一个函数。当你调用noisy时,它会返回一个新函数(这意味着noisy(Boolean)返回一个函数)。捕获发生是因为新函数可以访问任何有噪声的参数,包括f参数(程序员将此概念称为闭包)。如果noisy(Boolean)(1)内部函数内的f指的是Boolean。因此,valBoolean(1)开始设置为var val = f(arg)