简体   繁体   中英

Javascript function argument by reference

The code is from Eloquent Functional Programming. I have trouble understanding the test(element). If the test(element) is referencing equals(x), then is element = 0 since there is only one parameter?

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);
}

Previous code

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;
}

element does not get its value from x .

Rather, element refers to a parameter which will have it's value supplied when the function is invoked - by count in this case. The variable x , a parameter in the outer scope, is bound in scope of the function/closure that is returned when equals is invoked. That is, equals(0) evaluates to a function/closure which is then used as a predicate to count .

First, let's use equals directly, bearing in mind that equals evaluates to a function as does equals(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`

But because that's a bit hard to abstractly see, let's give the closure a name:

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);

Which we could imagine was written like this:

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

The difference being, of course, that in the above function the value ( 0 ) is hard-coded, while in the closure-creating equals it is whatever the bound x variable evaluates to.

(For more wonderful goodness on closures, see How do JavaScript closures work? )

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

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