在http://eloquentjavascript.net/1st_edition/chapter6.html中,有以下示例:
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
alert(isNotNaN(NaN));
只知道基本的Javascript和命令式编程,我对这种编程风格感到困惑。有人可以帮我理解运行期间会发生什么。
我介绍了代码并检查了变量,发现x
的值为NaN
。它是如何知道isNaN
的参数应该作为匿名函数的参数x
传递的?首先,为什么isNotNaN
的实际参数NaN成为isNaN
的参数(即isNaN
期望参数,为什么它从{{1}的参数中取出}})?
答案 0 :(得分:1)
理解这一点的最佳方式可能是看到这些事情实际上是平等的。请注意func
如何成为传递的isNaN
函数。
function negate(func) {
return function(x) {
return !func(x);
};
}
var isNotNaN = negate(isNaN);
/*
isNotNaN = function(x){
return !isNaN(x)
}
*/
alert(isNotNaN(NaN));
答案 1 :(得分:0)
请注意negate
都接受函数作为参数并返回一个函数。返回的函数将调用参数函数,否定返回值。因此,isNotNaN
是一个功能。调用它时,它会调用最初传递到negate
的函数,在本例中为isNaN
。无论您拨打isNotNaN
的是什么,都会传递给isNaN
。
实质上,您正在使用其他功能配置功能。使用更简单的(无参数函数)示例可能更容易看到:
function addX(x) {
return function(y) {
return x+y;
};
}
var add2 = addX(2);
console.log(add2(2)); // 4
var add3 = addX(3);
console.log(add3(7)); // 10
现在,更进一步,假设您将函数传递给addX
而不是值。
顺便说一句,这称为currying。
答案 2 :(得分:0)
这是因为你设置了这个:
var isNotNaN = negate(isNaN);
当调用isNotNaN(x)时,就像你调用negate(isNaN)(x)一样。你也可以在这里使用命名函数而不是匿名函数,所以我们说:
function negate(func) {
return xValue.call(this, x); //to be in the context of the xValue function
};
}
var isNotNaN = negate(isNaN);
alert(isNotNaN(NaN));
function xValue(x) {
return !func(x);
}
But then you have to take care about the context.