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