Search code examples
javascriptcallbackscopeargumentsreturn-value

Does arr.filter call callbackFn twice?


First time asker.

I came across this code from the page below:

function inBetween(a, b) {
  return function(x) {
    return x >= a && x <= b;
  };
}

let arr = [1, 2, 3, 4, 5, 6, 7];
alert( arr.filter(inBetween(3, 6)) ); // 3,4,5,6

https://javascript.info/closure#filter-through-function

Basically, the perpose of this function is to invoke arr.filter() such that only the values between X and Y are are returned: arr.filter(inBetween(3, 6)).

I should say that the perpose of this activity is to demonstrate scope and closure.

Now this is what I do not understand: Why is arr.filter not failing with an error from receiving a pointer/reference to another function from inBetween() instead of a boolean value?

Seeing that the code workds, it appears that arr.filter is invoking the return function of inBetween() as well, but should'nt a callback function parameter be invoked only once per item?

I thought that arr.filter(inBetween(3, 6)) would fail, expecting filter will receive a pointer instead of a boolean value. But arr.filter actially seems to call the return funtion as well, which I do not expect.

Looking at the code below:

function hello(){
  return function (){
    return 'hello'
  }
}

alert(hello()) returns a pointer to a funtion. In order to have the second funtion return the string value, the return function from hello() would need to be called as well alert(hello()())

Is this what arr.filter is doing? If yes, then I totally did not expect that, since I expect only the immediate function to be called, and not the return as well.

Could someone kindly clarify what is happening here?


Solution

  • arr.filter expects to be passed a function. For example, if you write this:

    arr.filter((x) => x >= 3 && x <= 6)
    

    When this code executes it starts by creating a function with the text (x) => x >= 3 && x <= 6. Now that that function has been created, it gets passed into arr.filter. arr.filter will then call that function for each element of the array.

    In your code you're doing much the same, you just changed how you're creating the function. You called inBetween(3, 6) which creates and returns a function. Then you pass the returned function into arr.filter. As before, arr.filter will then call the function you passed in for each element of the array. array.filter doesn't know how this function was created, so it doesn't know that inBetween exists.