Yashar Feizi
Yashar Feizi

Reputation: 41

Callbacks and Higher Order functions Javascript

This is a problem from chapter 5 of Eloquent JS http://eloquentjavascript.net/05_higher_order.html

function noisy(f) {
  return function(arg) {
     console.log("calling with", arg);
     var val = f(arg);
     console.log("called with", arg, "- got", val);
     return val;
   };
 }
noisy(Boolean)(12);
// → calling with 0
// → called with 0 - got false

Can someone please explain how f(arg) makes sense? I mean he is calling the argument f on another argument arg?? I am very confused.

How about the part that has return val; Why does that have to be there? When I delete it, the code still runs like it should.

Lastly, can some explain the code interpretation line by line? How does passing boolean make sense in the example?

Thank you so much

Upvotes: 0

Views: 1253

Answers (3)

maioman
maioman

Reputation: 18734

keeping it simple:

the argument in function noisy (that acts as a wrapper) is actually just

(Boolean());

(for ref on boolean-type check this).

Furthermore you use 0 as argument of console.log in the inner function,
and as the argument of Boolean() (in var val).


How about the part that has return val; Why does that have to be there? When I delete it, the code still runs like it should.

as long as you're using console.log you're not actually using the return statement, but if you were to do this

console.log(noisy(Boolean)(0))

you can see the return statement after the previous console.logs

Upvotes: 0

collapsar
collapsar

Reputation: 17238

Basics:

noisy maps a function to another function that does the same as the original but writes input and output value ( moreprecisely their string representations) to the console.

  • Q1: The intention seems to be the enhancement of object constructors with a simple logging facility to show which initialization arguments produce which kind of object state. To this end, noisy returns a function object - the original function enhanced by output to the console.

  • Q2: The enhanced Boolean constructor is called without assigning its return value. Thus it makes no difference to the code whether the enhanced constructor does return a value or not.

  • Q3: Boolean reveals what boolean values you get for different initialization arguments. I guess the lesson to be learned is that a numerical of 0 gets you a false, anything else true (the latter is informed guessing on my part, but with noisy you have a tool to generically check that for arbitrary constructors and initialization values).

Upvotes: 1

jfriend00
jfriend00

Reputation: 707238

One simple rule to remember is that nested functions in Javascript (e.g. functions declared within other functions) have access to all the variables and arguments of their parent functions.

When noisy(f) is called and it returns another function, that creates a closure in Javascript. That means that even though noisy(f) has finished execution, it's arguments and any local variables are still alive and can still be used by the inner function.

So, when that inner function is then called, it has full access to the f argument from the prior execution of its parent function. Here's an MDN reference on closures which might be worth reading and a StackOverflow answer explaining closures.

So, let's break down what your code is doing step by step:

function noisy(f) {
  return function(arg) {
     console.log("calling with", arg);
     var val = f(arg);
     console.log("called with", arg, "- got", val);
     return val;
   };
 }

// split up noisy(Boolean)(12); into two steps
var temp = noisy(Boolean);
temp(12);

When noisy(Boolean) is called, that returns the inner function and for any future invocation of that inner function, the f argument is set to the Boolean constructor function.

When that returned function is then called with it's own argument as in temp(12) above, then it ends up executing Boolean(12) and returning that (who's value will be true).

Working demo: http://jsfiddle.net/jfriend00/mkn839gu/

Upvotes: 1

Related Questions