Javascript函数参数引用

时间:2014-02-09 00:19:02

标签: javascript

代码来自Eloquent Functional Programming。我无法理解测试(元素)。如果test(element)引用equals(x),那么element = 0,因为只有一个参数?

function count(test, array) {
    return reduce(function(total, element) {
        return total + (test(element) ? 1 : 0); 
    }, 0, array);
}

function equals(x) {
    return function(element) {return x === element;}; // element gets value from x?
}

function countZeroes(array) {
    return count(equals(0), array);
}

以前的代码

function forEach(array, action) {
    for (var i = 0; i < array.length; i++)
        action(array[i]);
}

function reduce(counter, base, array) {
    var total = 0;
    forEach(array, function (element) {
        total += counter(element);
    });
    return total;
}

1 个答案:

答案 0 :(得分:1)

element x获取其值。

相反,element指的是一个参数,它将在调用函数时提供它的值 - 在这种情况下由count提供。变量x外部范围中的参数,绑定在调用equals时返回的函数/闭包的范围内。也就是说,equals(0) 计算为函数/闭包,然后将其用作count的谓词。

首先,让我们直接使用equals,记住equalsequals(0)一样评估函数:

   equals(0)(1) // -> false, x=0, element=1
   equals(0)(0) // -> true,  x=0, element=0
// ^^^^^^^^^    - invokes equals(..), evaluates to the closure binding `x`
//          ^^^ - invokes the previously returned closure, supplying `element`

但是因为抽象地看起来有点困难,让我们给闭包一个名字:

var equalToZero = equals(0)  // -> function, x=0
//                ^^^^^^^^^ - invokes equals(..), evaluates to the closure binding `x`
   equalToZero(1)            // -> false, x=0, element=1
   equalToZero(0)            // -> true,  x=0, element=0
// ^^^^^^^^^^^^^^ - invokes the previously returned closure, supplying `element`

// And just as before, it is the `count` function that
// supplies the `element` argument when it invokes the function.
// (The function is locally known by the name `equalToZero`.)
count(equalToZero, array);

我们可以想象的是这样写的:

function equalToZero (element) {
    return 0 === element;
}

当然,差异在于,在上面的函数中,值(0)是硬编码的,而在创建闭包的equals中,它是绑定的x变量评估为。

(关于闭包的更多精彩,请参阅How do JavaScript closures work?