'Why is variable definition not hoisted in JS but function

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?



Solution 1:[1]

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')
}

Solution 2:[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();

Solution 3:[3]

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.

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 cccn
Solution 2
Solution 3 Gabor