How are parameters handled when passing functions to Javascript?

The following example is provided at http://eloquentjavascript.net/1st_edition/chapter6.html :

function negate(func) { return function(x) { return !func(x); }; } var isNotNaN = negate(isNaN); alert(isNotNaN(NaN)); 

Knowing only basic Javascript and imperative programming, I am puzzled by this programming style. Can someone help me understand what happens at runtime.

I went through the code and checked the variables and found that the value of x is NaN . How does he know that the argument isNaN should be passed as argument x an anonymous function? First, why does the actual parameter NaN isNotNaN become the argument of isNaN (i.e., while isNaN expects an argument, why does it take it from the argument of isNotNaN )?

+6
source share
3 answers

The best way to understand this may be to see that these things are actually equal. Notice how func becomes the passed function isNaN .

 function negate(func) { return function(x) { return !func(x); }; } var isNotNaN = negate(isNaN); /* isNotNaN = function(x){ return !isNaN(x) } */ alert(isNotNaN(NaN)); 
+1
source

Note that negate both take a function as an argument and return a function. The returned function will call the argument function, negating the return value. So isNotNaN is a function. When it is called, it will call the function originally passed to negate , in this case isNaN . Everything you call isNotNaN with will be passed to isNaN .

Essentially, you are setting up a function using another function. This might be easier to see with a simpler (without argument function):

 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 

Now take one more step and imagine that you passed the function to addX instead of the value.

By the way, this is called currying .

0
source

This is because you install this:

  var isNotNaN = negate(isNaN); 

And when calling isNotNaN (x), so you call negate (isNaN) (x). You can also use a named function instead of an anonymous one, so we say:

  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. 
0
source

All Articles