13

I'm having a bit of trouble understanding why my code works. I'm expecting a reference error, but everything works fine.

My code:

const functionA = () => { let bResult = functionB(); console.log("Function A " + bResult); }; const functionB = () => { return "Function B"; }; functionA(); 

I get this output (no errors);

λ node test.js Function A Function B 

As I understand it, only function declarations are hoisted (not function expressions) http://adripofjavascript.com/blog/drips/variable-and-function-hoisting.html.

Thus, shouldn't I expect an error as FunctionB isn't defined before it's called in FunctionA? Am I missing somewhere here?

EDIT: Thanks for the answers everyone, I think I figured it out. It's indeed not getting hoisted because if I call functionA at the beginning, it gives me an error.

functionA(); // ReferenceError: functionA is not defined const functionA = () => { let bResult = functionB(); console.log("Function A " + bResult); }; const functionB = () => { return "Function B"; }; 

So it's not a question of hoisting. Rather, by the time functionA is called at the end of the file, both functionA and functionB have been defined.

15
  • 8
    by the time functionA is actually executed, functionB will be set. So this works just fine. It would be terribly annoying if you had to define all of your functions "in order". Not to mention, mutual recursion depends on this behavior. Commented Feb 28, 2019 at 20:27
  • 1
    @user633183 functionB is set, but it's referred to in functionA before it's defined. Why doesn't it need to be defined in advance given that it isn't hoisted Commented Feb 28, 2019 at 20:29
  • 1
    Try doing: const functionA = () => {..}; functionA(); const functionB = () => {..} Commented Feb 28, 2019 at 20:29
  • 3
    @m0meni because functionB is hoisted and the identifier is available immediately. However, the value for functionB is not ready to use until functionB is actually defined. Adiga's comment about running functionA() before the functionB = ... will show the "problematic" behavior. Commented Feb 28, 2019 at 20:32
  • 1
    @m0meni precisely Commented Feb 28, 2019 at 20:33

1 Answer 1

6

As someone else pointed out, by the time functionA is called, functionB is now loaded into memory.

Compare the following:

const functionA = functionB; const functionB = () => { return "Function B"; }; functionA(); 

This will throw 'Uncaught ReferenceError: functionB is not defined'

Compare that behavior to this:

const functionA = functionB function functionB(){ return "Function B"; }; functionA(); 

The second one actually works, because functionB is hoisted above your constant declaration.

Sign up to request clarification or add additional context in comments.

3 Comments

I hope you don't mind the edit. I was writing it as a separate answer but the question was closed before I could finish it.
@user633183 I've rolled back the edit as it was incorrect about how hoisting works.
In your former example(arrow function) const variable functionB gets hoisted but it has value undefined. Your former example will give error: Uncaught ReferenceError: Cannot access 'functionB' before initialization

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.