0

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

3 Answers3

1

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/

Community
  • 1
  • 1
jfriend00
  • 683,504
  • 96
  • 985
  • 979
  • @YasharFeizi - Did this answer your question? Since it looks like you are perhaps new to StackOverflow, are you aware that if you get your question answered, then you should select the best answer and click the green checkmark to the left of the answer. This will inform the community that your question has been answered and earn both you and the person supplying the answer with some reputation points. – jfriend00 Feb 27 '15 at 04:25
1

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

collapsar
  • 17,010
  • 4
  • 35
  • 61
0

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

maioman
  • 18,154
  • 4
  • 36
  • 42