3

I am learning JS and i am curious about why a function can be called before its defined & yet run fine. I understand that its due to hoisting wherein the code is scanned upfront to bring in declared variables & functions in scope.

If it were just brining the declarations of these entities in scope, why doesn't a function call also return undefined(or something similar) when being called before its definition - like variables do?

7
  • 3
    Likely for code organisation purposes. You can define a function at the bottom of the file and call it at the top. But it makes less sense to do that with a variable. Although I can't say this is the exact reasoning used when this was designed. Commented Nov 3, 2019 at 11:47
  • 3
    Also, just to point out - variable definitions are hoisted. That's why you get undefined instead of ReferenceError: <variable> is not defined. The assignment not processed until the actual var variable = "some value" line. Commented Nov 3, 2019 at 11:49
  • the 1st comment makes sense, but i would disagree with 2nd. in this statement "var x = 5;" If x is accessed before , it says undefined ; which implies the exact definition is not hoisted. since it does not give a reference error , i would say its the declaration thats hoisted. Because its same if the statement were "var x" Commented Nov 3, 2019 at 11:56
  • @nikel I think the second comment is correct. The var declaration is hoisted, the assignment is not. Commented Nov 3, 2019 at 12:16
  • @VLAZ I think you're right overall, but it would make sense for a variable if that variable refers to a function Commented Nov 3, 2019 at 12:22

3 Answers 3

3

As VLAZ pointed out in the comment, variables definition are hoisted as well. Consider this example:

console.log(a) // undefined a = 2 console.log(a) // 2 var a console.log(b) // ReferenceError: b is not defined

We can say that undefined is about a value of variable a. Function declarations are hoisted in the same way, but function expressions are not:

foo() // foo bar() // TypeError: bar is not a function function foo () { console.log('foo') } var bar = function () { console.log('bar') }

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

Comments

2

The difference is declaration with var is a VariableDeclaration, while declaration with function key word is a FunctionDeclaration.

The FunctionDeclaration is hoisted all together, and unlike VariableDeclaration, it has a body field, which contains the body of a function. You can spot this kind of differences using ESLint parser.

This is why:

someFunc(); function someFunc(){ console.log('someFunc'); } // hoisted as FunctionDeclaration var someOtherFunc = () => {console.log('someOtherFunc');}; // not hoisted because the value of the variable is a function expression var someNewFunc = function () {console.log('someNewFunc');}; // not hoisted because the value of the variable is a function expression someOtherFunc(); someNewFunc(); 

5 Comments

That's not quite correct. the var declaration is hoisted to the top of the enclosing scope, const does not. Both are undefined until the assignment is executed
You are correct, but I'm explaining specifically hoisting of VariableDeclaration vs hoisting of FunctionDeclaration, and pointing out, that function body will not appear anywhere except FunctionDeclaration. I see the confusion here, so will change the 2nd declaration to var.
Yeah, but you increased the conceptual space by adding const which isn't in the question
@AluanHaddad actually, const declarations are hoisted. Not initialisations. The reason myVar = 5; let myVar throws an error is because it knows that let myVar exists further down in scope. That information comes from hoisting the declaration. It's the initialisation phase that is not hoisted and only occurs at the line let myVar. This is why the error message reads can't access lexical declaration myVar' before initialization` - it's not initialised. Were it not declared at all, the error message would be myVar is not defined.
That is a nice clarification, I appreciate it.
0

I have found a good explanation of why the variable is undefined at the point when it is hoisted which may look like a different behaviour if you compare it to how a function declaration is hoisted:

"JavaScript only hoists declarations, not initializations" MDN website:

However JavaScript only hoists declarations, not initializations! This means that initialization doesn't happen until the associated line of code is executed, even if the variable was originally initialized then declared, or declared and initialized in the same line.

var x = 3 

x -> hoisted, becuse the JS engine come across a declarion (reserve the memory for the variable) but during the hoisting the variable won't be intislaized which means the value won't be assigned (remain undefined)

If you compare it to a function declaration,

function a() = { ... } 

this doesn't have an initialization (the function isn't called), this is just a declaration.

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.