Javascript中的高阶函数

Hoo*_*lum 18 javascript function higher-order-functions

我正在阅读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
Run Code Online (Sandbox Code Playgroud)
  1. 为什么这个函数的调用会像这样嘈杂?(布尔)是演员吗?为什么演员?返回值?还是论点?为什么不(布尔值)嘈杂(0)如果它的返回值.或者噪声((布尔值)0)如果参数是被转换的参数.

    noisy(Boolean)(0)
    
    Run Code Online (Sandbox Code Playgroud)
  2. 这一行发生了什么?f()甚至定义在哪里?

    var val = f(arg);
    
    Run Code Online (Sandbox Code Playgroud)

T.J*_*der 21

  1. Boolean是一个功能.这是你间接通过的功能noisy.我知道,有点令人困惑,因为它看起来像一个类型的名称.但在JavaScript中,那些最初皑皑的东西(Boolean,Number,String,等等)是函数.当你调用Boolean(使用new)时,它会尝试将你给它的参数转换为boolean原始值并返回结果.(参见规范中的§15.6.1)

  2. fnoisy函数中参数的名称.

JavaScript中的函数是一流的对象.您可以将它们作为参数传递给其他函数,就像任何其他对象一样.

当你这样做

noisy(Boolean)(0)
Run Code Online (Sandbox Code Playgroud)

有两件事情在发生.第一:

// (In effect, we're not really creating a variable...)
var x = noisy(Boolean);
Run Code Online (Sandbox Code Playgroud)

这给了我们一个函数,当被调用时,它将调用Boolean我们给出的参数,同时也执行这些console.log语句.这是您在noisy(return function(arg)...)中看到的功能;

然后我们调用该函数:

x(0);
Run Code Online (Sandbox Code Playgroud)

当你看到控制台输出时就是这样.因为Boolean(0)就是false,你看到Boolean返回值.

这是一个更简单的例子:

function foo(bar) {
    bar();
}
function testing() {
    alert("testing got called");
}
foo(testing);
Run Code Online (Sandbox Code Playgroud)

在那里,我传递函数testingfoo.我正在使用的参数名称foobar.该行bar();调用该函数.


Blu*_*lue 9

没有()的函数是实际函数.带()的函数是函数的调用.另请注意,JavaScript是一种松散类型的语言,因此您不要声明变量类型.我已经为你的例子添加了一些评论来尝试和帮助.

// We define a function named noisy that takes in an argument named f. We are expecting f to be a function but this isn't enforced till the interpreter throws an error. 
function noisy(f) {
// Noisy returns a single item, an anonymous function. That anonymous function takes in an argument named arg
  return function(arg) {
    console.log("calling with", arg);
// Our anonymous function then takes f (It can use f because its defined inside noisy, see closures for more details) and invokes it with the argument arg and stores the result in a variable named val. 
    var val = f(arg);
    console.log("called with", arg, "- got", val);
// It now returns val
    return val;
  };
}
Run Code Online (Sandbox Code Playgroud)

那么吵闹(布尔)(0)就是这样的

f是布尔值函数

吵闹返回这样的功能

function(arg) {
  var val = Boolean(arg);
  return val;
}
Run Code Online (Sandbox Code Playgroud)

所以现在我们有了

我们返回的函数(0)

它会像正常一样执行

function(0) {
  var val = Boolean(0); // false
  return val;
}
Run Code Online (Sandbox Code Playgroud)


小智 5

我对JS比较陌生,我也只是阅读了Eloquent Javascript,一旦我理解了函数的调用(回答你的观点1),我发现它更容易理解:

noisy(Boolean)(0);
Run Code Online (Sandbox Code Playgroud)

noisy(Boolean)创建一个新的功能和(0)因为它正作为一个参数成新的功能是传递后.如果您回头看大于示例:

function greaterThan(n) {
  return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));
Run Code Online (Sandbox Code Playgroud)

它也可以这样调用:

greaterThan(10)(11);
Run Code Online (Sandbox Code Playgroud)

我希望这澄清你的第一个问题,为什么这样称呼它.

对于第二个问题.该f在:

var val = f(arg);
Run Code Online (Sandbox Code Playgroud)

是输入时Boolean传入的函数.然后它被用作嘈杂函数中的参数.我也没有意识到布尔本身就是一个函数,而不仅仅是数据类型.正如其他人所说 - 它将你给它的参数转换为布尔值并返回结果.noisynoisy(Boolean)

因此val变得Boolean(arg)成为Boolean(0)将计算得到false.如果您尝试通话,noisy(Boolean)(1);您将看到它返回true.在console.log("called with", arg, "- got", val);简单地记录(在此情况下0)参数和评价它(假)的结果.

实际上,它已将布尔函数更改为记录参数和结果的函数,以及返回结果.

我希望这有帮助.只是写它有助于我自己的理解.