Basics of Anonymous Functions

Basics of Anonymous Functions
0.0 0

#1

I’d like to know what is up with functions like these.
All this function does basically is it returns a number incrementing it by 1.


const increment = function() {
  "use strict";
  return function increment(number, value=1) {
    return number + value;
  };
}();
console.log(increment(5, 2)); // returns 7
console.log(increment(5)); // returns NaN

But so does this function

const increment=function(num){
    return num+1;
};

I guess my question is why these nested redundant functions?
And when we call the increment function in the first case, are we calling the const increment or function increment? How’s it that we can name a function the same as a const? Isn’t it cofusing?
Your browser information:

User Agent is: Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.99 Safari/537.36.

Link to the challenge:
https://learn.freecodecamp.org/javascript-algorithms-and-data-structures/es6/set-default-parameters-for-your-functions


#2

It’s to either to allow the tests to run properly or to stop browser errors in some browsers, I’m not sure of the exact reasoning here, someone who has worked on the codebase will probably have a better answer. I was trying to dig through issues on the Free Code Camp codebase to figure out why the ES6 challenges have been written like this, but I couldn’t find anything useful regarding the reasoning behind it. In reality, you’d generally write it like you say, without wrapping it in an anonymous function: that wrapper doesn’t have anything specifically to do with the task you have to do in the challenge beyond scoping the contents (+ I’ve noticed that for the challenges I’ve tried, if you just write it without the anonymous function, it will work fine and you’ll pass.)


#3

Can you answer the second part of my question please? Thanks!


#4

It’s a self executing function - if you look at it, it’s like const increment = function(){}(), and that () at the end is saying execute. So when you call increment it immediately executes the contents of it.

And JS has function scope - the stuff inside a function is isolated to that function. So you could do something like:

const foo = () => {
  const foo = 'level 1'
  console.log(foo)
  return function() {
    const foo = 'level 2'
    console.log(foo)
    return function() {
      const foo = 'level 3'
      console.log(foo)
    }
  }
}

And it’s pretty confusing code, but if you call it, it’ll work fine:

> foo()()()
level 1
level 2
level 3

This is why I think it’s for the benefit of the tests. The increment inside is the one that gets tested, and the tests need to check that you have included certain things, they don’t just check that given an input, you get a certain output. I may be off base with my reasoning, but that seems to make sense to me. It seems to be necessary to run things properly, but it’s not very learner-friendly, it’s an implementation detail leaking through that ideally shouldn’t be exposed

Basically, avoid writing code like this in real life because it’s super confusing - it’s called shadowing and it’s generally an antipattern:


#5

You’ve been kind. Thank you.
One thing, though.
Aren’t const variables not supposed to be reassigned? How come we’re allowed to use the same name for a function and a const variable?(in the increment function)


#6

Identifiers like const can’t be reassigned within the same scope: inside the function is a new environment, a different scope - this is why, in the example above, I can keep defining a constant called foo.

http://2ality.com/2015/02/es6-scoping.html