0

I have a miss understanding, is the strainer function an example the downward funarg problem? I was using the chrome debugger under the sources panel and noticed this under the scope section.

screenshot of my description

Is the strainer function param cb a closure or is the function strainer the closure? I'm finding it difficult to sort through the information about closures and the funarg problem on the web. I clearly don't understand the funarg problem or closures and need some help?

function strainer(collection, cb) {
  return collection.reduce(function inner(acc, curr) {
    if (cb(curr)) {
      return acc.concat(curr);
    }
    return acc;
  }, []);
}

function even(number) {
  if (number % 2 === 0) {
    return true;
  }
  return false;
}

var collection = [1, 2, 3, 4, 5];

strainer(collection, even);

Background: I was under the impression private variables returned to an outer environment created closures but the example looks like something different.

The flintstones function example below has closure over the scope of the quotes function.(I think this is the upward funarg problem)

function quotes() {
  var x = 'yabba dabba doo!';
  return function flintstones() {
    return x;
  }
}

var fredSays = quotes();
fredSays();
Bergi
  • 630,263
  • 148
  • 957
  • 1,375

1 Answers1

5

Is the strainer function param cb a closure or is the function strainer the closure?

Neither, actually. inner is the closure. You are inspecting the scope chain of inner here - it has local acc and curr variables, and free variable cb that closed over the cb variable from the strainer scope. That's what the debugger is trying to show you. The cb part of the strainer scope is not allocated on the stack but in the heap, however the debugger doesn't display that detail.

Yes, this is more or less the downward funarg problem. inner is passed to reduce here, and that's why we create a closure for it. Notice that the distinction between upward and downward is meaningless in JS, since we never know what the called function does with the passed callback - it might as well stow it away somewhere. Proving that it stays contained in and does not escape the call is not done.

Bergi
  • 630,263
  • 148
  • 957
  • 1,375
  • thank you, the https://developers.google.com/web/tools/chrome-devtools/javascript/step-code doesn't elaborate as to what I'm exactly looking at as the way you have. "Not sure why you care about those optimization details though": As an entrance assessment question for a coding bootcamp, I was asked to rebuild the arrays filter method w/ reduce. After the assessment I was stepping through the function as a check to see if I knew what I was doing. When I saw 'Closure' under the scope pane, I thought, 'oh sh*t, why is this closure here?' I feel more comfortable now after your explanation. – The cows are in the Meadow Jun 15 '17 at 20:07
  • The ["scope" section](https://developers.google.com/web/tools/chrome-devtools/javascript/step-code#scope) states "*The Scope pane shows you properties defined at the local, closure, and global levels.*" :-) OK, an understanding of closures is a good thing, I've just never seen anyone going the theoretical route and learning about the funarg problem for that. – Bergi Jun 15 '17 at 20:15