5

Recently I was confused about javascript hoisting behavior and now I got stuck with that.

So, there are two examples.

var alpha = 'alpha';

var beta = 'beta';

f(); //beta


var f = function f1() {
    console.log(beta);
};

function f() {
    console.log(alpha);
}

f(); // alpha

The first one is working as expected, because the function declaration overwrite our variable f (with value "undefined") when Javascript is set up the Lexical Environment.

But the second gives me a push, that I does not understand something.

var alpha = 'alpha';

var beta = 'beta';

f();  // - alpha


function f() {
    console.log(alpha);
}

var f = function f1() {
    console.log(beta);
};


f(); // beta

Why the variable f did'nt hoisted to the top of out code, and overwrite our hoisted function before? Why in "first f" call I recieve "alpha". I think, that it must be an error like: "f is not a function", because in first f call I excepect, that the f would be "undefined".

Avernikoz
  • 463
  • 2
  • 5
  • 15
  • 1
    technically, the two snippets are the same – Jaromanda X Apr 18 '18 at 12:39
  • 1
    You might find [**this answer**](https://stackoverflow.com/a/3344397/6182569) useful. – Mihailo Apr 18 '18 at 12:41
  • Thanks for all answers. Maybe this statement can help somebody who did'nt understand this thing like me: So that covers variable hoisting, but what about function hoisting? Despite both being called "hoisting," the behavior is actually quite different. Unlike variables, a function declaration doesn't just hoist the function's name. **It also hoists the actual function definition.** – Avernikoz Apr 18 '18 at 15:48

2 Answers2

2

Given var foo = something, only the variable declaration is hoisted.

This means that var foo is hoisted but the foo = something will run in the reading order.

Given function foo() {}, the variable declaration and function assignment are both hoisted. This creates the variable foo and gives it the value of the function.

If you have both of the above, then you declare the variable twice (for no extra effect) and assign it the value of the function (as that is the only assignment).

So in your second example…

The function declaration is hoisted, so f(); // - first f calls that.

The assignment of the function expression is not hoisted, but f(); // ** - second f appears after it in normal reading order, so the second call to foo() hits that.

Quentin
  • 914,110
  • 126
  • 1,211
  • 1,335
1

technically, the two snippets are the same

something like

function f() {
    console.log(alpha);
}
var alpha = 'alpha';
var beta = 'beta';
var f; // ignored because f is already defined
f();  // - first f
f = function f1() {
    console.log(beta);
};
f(); // ** - second f

or perhaps - though, I'm pretty sure function are "hoisted" first

var alpha = 'alpha';
var beta = 'beta';
var f;
function f() {
    console.log(alpha);
}
f();  // - first f
f = function f1() {
    console.log(beta);
};
f(); // ** - second f
Jaromanda X
  • 53,868
  • 5
  • 73
  • 87