繁体   English   中英

Javascript 中的高阶函数

[英]Higher-order functions in Javascript

我正在阅读 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
  1. 为什么对函数的调用会像这样嘈杂? (Boolean) 是演员表吗? 演员表干什么? 返回值? 还是论点? 为什么不是 (Boolean)noisy(0) 如果它的返回值。 如果参数是被转换的参数,则为noise((Boolean) 0)。

     noisy(Boolean)(0)
  2. 这条线发生了什么? f() 在哪里定义?

     var val = f(arg);
  1. Boolean是一个函数。 这是您通过noisy间接调用的函数。 我知道这有点令人困惑,因为它看起来像一个类型的名称。 但是在 JavaScript 中,那些最初限定的东西( BooleanNumberString等)是函数 当您调用Boolean使用new )时,它会尝试将您提供的参数转换为boolean原始值并返回结果。 (请参阅规范中的第15.6.1 节。)

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

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

当你做

noisy(Boolean)(0)

有两件事正在发生。 第一的:

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

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

然后我们调用该函数:

x(0);

这就是您看到控制台输出的时候。 由于Boolean(0)false ,您会看到Boolean返回该值。

这是一个更简单的例子:

function foo(bar) {
    bar();
}
function testing() {
    alert("testing got called");
}
foo(testing);

在那里,我将功能testing传递给foo 我在foo使用的参数名称是bar 线条bar(); 调用函数。

没有 () 的函数才是真正的函数。 带有 () 的函数是对该函数的调用。 另请记住,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;
  };
}

那么noise(Boolean)(0) 的工作方式是这样的

f 是函数布尔值

嘈杂的返回这样的函数

function(arg) {
  var val = Boolean(arg);
  return val;
}

所以现在我们有

我们返回的函数(0)

它像正常一样执行成为

function(0) {
  var val = Boolean(0); // false
  return val;
}

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

noisy(Boolean)(0);

noisy(Boolean)创建了一个新函数,并且(0)在它之后,因为它被作为参数传递到该新函数中。 如果您参考大于示例:

function greaterThan(n) {
  return function(m) { return m > n; };
}
var greaterThan10 = greaterThan(10);
console.log(greaterThan10(11));

也可以这样调用:

greaterThan(10)(11);

我希望能澄清您关于为什么这样称呼它的第一个问题。

对于第二个问题。 中的f

var val = f(arg);

是在输入noisy(Boolean)时传入noisyBoolean函数。 然后它被用作噪声函数中的参数。 我也没有意识到 Boolean 本身可以是一个函数,而不仅仅是一种数据类型。 正如其他人所说 - 它将您提供的参数转换为布尔值并返回结果。

因此val变为Boolean(arg) ,它变为Boolean(0) ,其计算结果为false 如果你尝试调用noisy(Boolean)(1); 你会看到它返回true console.log("called with", arg, "- got", val); 简单地记录参数(在这种情况下为 0)和评估它的结果(假)。

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

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

Javascript 变量没有静态数据类型。 也可以为它们分配不同数据类型的变量。

JS 中没有类型转换的概念,如 JAVA 等。

() 在函数调用中对应于函数的调用。

在这里,Boolean 似乎是一个高阶函数,它作为参数传递给有噪声的函数。 噪声函数的结果将是

 function(arg) { console.log("calling with", arg); var val = f(arg); console.log("called with", arg, "- got", val); return val; };

带有 0 的第二个括号用于调用此结果。

在这里,在上面的函数中,注意下面的行。

 var val = f(arg);

这里,f 对应于之前传递的布尔函数。 arg 对应于 0。

由于返回了 val,因此表达式的结果将是 Booelan(0) 的结果。

如果你仍然有这个问题,这就是我的理解(它也让我头疼..)

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)

函数只是一个常规值。 上一句话是理解这里发生的事情的关键。

我们的 noise(f) 函数是一个值。 这就是它返回的内容。

noise(f) 返回一个带有参数 (arg) 的函数。

noise(f) 也接受一个参数 (f)。 内部函数(从函数内部调用的函数)可以访问传递给外部函数的变量和参数。

我们正在调用我们的外部函数并将参数布尔值传递给它。 我们的外部函数返回它的内部函数,它接受一个参数 (0)。 通过理解上面的内容,应该很清楚 Noise(Boolean(0)) 只会将一个参数传递给我们的外部函数,而不会将任何内容传递给我们的外部函数返回的内部函数。

真的很简单。 现在我们理解了它,很难相信它让我们开始如此头疼...... */`

暂无
暂无

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

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