1

Given the code:

function stuff() {
    console.log('stuffing');
}

stuff = stuff;

stuffy = () => stuff();

stuffx = () => console.log('tobi');
function stuffers(stuff = stuffx) {
    stuff();
    stuffy();
}

stuffers();

The result is what one would expect:

tobi
stuffing

But when changing the stuffers function signature like this:

function stuff() {
    console.log('stuffing');
}

stuff = stuff;

stuffy = () => stuff();

stuffx = () => console.log('tobi');
function stuffers(stuff = stuff) {
    stuff();
    stuffy();
}

stuffers();

The result is:

ReferenceError: stuff is not defined

Why is this happening ONLY in the case of having the same name?

  • stuff = stuff? what you want to achieve..? – sumeet kumar Jan 11 '18 at 15:08
  • Why are you doing `stuff = stuff;`? stuff is already a function object above – Liam Jan 11 '18 at 15:08
  • 2
    Because `stuff` in the context of the `stuffers` function is a local variable (not the main `stuff` function first declared). YOu then assign it (the null one) to itself (effectively this is not doing anything), so thats why you get undefined. Basically, the new local `stuff` takes priority over the `stuff` function – musefan Jan 11 '18 at 15:08
  • [Sort of related/duplicate](https://stackoverflow.com/questions/39722854/default-parameters-in-es6-throws-error), but with only one parameter here. – James Thorpe Jan 11 '18 at 15:09
  • "Because stuff in the context of the stuffers function is a local variable (not the main stuff function first declared). YOu then assign it (the null one) to itself". But then why does the first version work, it also accesses the globally defined functions. If you would use stuffx = stuff it would also work, only when it has the same name as a globally defined function does it result in undefined. I wanted to understand why is it happening ONLY for the case of having the same name. – RandomCatGamer Jan 11 '18 at 15:19
  • @RandomCatGamer please check the babel link I provided. My answer was downvoted but I don't know why. If you see why, please let me know :) – xadhix Jan 11 '18 at 15:20
  • 1
    @RandomCatGamer: Because when you use the same name, the new local variable (`stuff`) takes priority, basically, it becomes the only `stuff` that the function knows about. It cannot reference the original `stuff` function. It works in the other examples, because there is no conflict. `stuffx = stuff` works because `stuffx` is the new local variable, and it is assigned with reference to the `stuff` function, which it can see correctly because there is no conflict – musefan Jan 11 '18 at 15:24
  • Possible duplicate of [What is the scope of variables in JavaScript?](https://stackoverflow.com/questions/500431/what-is-the-scope-of-variables-in-javascript) – Liam Jan 11 '18 at 15:31

1 Answers1

2

The main problem in Your case you're ovverriding the globally defined stuff function with it's local declaration. As xadhix mentioned, this declaration

function stuffers(stuff = stuff) {
    stuff();
    stuffy();
}

Compiles down to (i've split it to 3 parts to provide readable comments):

function stuffers() {
    var stuff; 

Above the globally defined stuff is redeclared in local context.

    stuff = arguments.length > 0 && arguments[0] !== undefined ? arguments[0] : stuff;

Here happens the default assigment from function declaration (stuff = stuff) , but the variable has already been reinitialized in this scope with undefined value, so it is simply assigning an undefined value again to the stuff variable (stuff = stuff)

    stuff(); //error
    stuffy();
}

This does not happen in "working" example as stuffx is not present in the local scope and the assigment stuff = stuffx does not produce undefined value.

The full snippet of what is actually executed from stuffers perspective is

function stuffers() {
    var stuff;
    stuff();
    stuffy();
}