[英]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
为什么对函数的调用会像这样嘈杂? (Boolean) 是演员表吗? 演员表干什么? 返回值? 还是论点? 为什么不是 (Boolean)noisy(0) 如果它的返回值。 如果参数是被转换的参数,则为noise((Boolean) 0)。
noisy(Boolean)(0)
这条线发生了什么? f() 在哪里定义?
var val = f(arg);
Boolean
是一个函数。 这是您通过noisy
间接调用的函数。 我知道这有点令人困惑,因为它看起来像一个类型的名称。 但是在 JavaScript 中,那些最初限定的东西( Boolean
、 Number
、 String
等)是函数。 当您调用Boolean
(不使用new
)时,它会尝试将您提供的参数转换为boolean
原始值并返回结果。 (请参阅规范中的第15.6.1 节。)
f
是noisy
函数中参数的名称。
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)
时传入noisy
的Boolean
函数。 然后它被用作噪声函数中的参数。 我也没有意识到 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.