2

JavaScript Hoisting confuses me. Is variable initialization hoisted ? i think it is hoisted because we access variable before we declare and initialize it

console.log(a);
var a = 4;
undefined
undefined

undefined shows that variable a is declare before code execute this is because of hoisting.

if i'm wrong please correct me.

j08691
  • 204,283
  • 31
  • 260
  • 272
  • 1
    Welcome to Stack Overflow - is this from the browser console? – Mikkel Jan 19 '20 at 20:26
  • 8
    The _declaration_ is hoisted; the _assignment_ occurs on the line at which it is written in the function. And, as @Mikkel is getting at (I think), this only matters in the function scope. – Alexander Nied Jan 19 '20 at 20:27
  • 4
    https://developer.mozilla.org/en-US/docs/Glossary/Hoisting#Only_declarations_are_hoisted MDN is always the first place to go for these things, and it's explained there. – ASDFGerte Jan 19 '20 at 20:29
  • A duplicate many times over .. a cookie to valid dupe-close links. – user2864740 Jan 19 '20 at 20:40

2 Answers2

4

TLDR

In JavaScript, both variable and function declarations are hoisted.

Initialization is not.


Hoisting means that - regardless of the lexical position of declaration - the identifier is semantically present from the very start of the enclosing code region (function or block).

This means identifiers (ie. variable names) are semantically present before the line of code at which they are declared - if only to guarantee confusion does not occur between identifiers with the same name.

Note that a hoisted identifier might not (eg if declared using let) be available for access by the developer until the declaration of the variable has been evaluated. ie. some time after the function or block has started executing. The formal name for this period is "Temporal Dead Zone".

In JavaScript, both variable and function declarations are hoisted.

Initialization is not.

For variables declared with var, the effect is that the declaration can be imagined to be at the very top of the enclosing function, regardless of the lexical (ie. in the code) position of the declaration.

For everything else in strict mode code (function, function*, let, const , class) the effect is that declarations can be imagined to be at the very top of the enclosing block (which might or might not be a function), regardless of their lexical position of declaration.

Non-strict code has a separate, more complicated set of rules for function statements enclosed within blocks. See also.

In the case of variables declared using var, the variable itself (with a default value of undefined) is available for assignment and dereferencing (reading its value) from the top of the enclosing execution context.

Hoisted var declarations are automatically initialized with undefined.

For everything else the runtime is aware of the identifier from the top of the enclosing block, but it is not available for assignment or dereferencing until the flow of execution has moved passed the point of lexical declaration. ie. that the Temporal Dead Zone has passed.

Hoisted function/function* declarations are immediately initialized with the hoisted function.

Note that in JavaScript, the algorithm for initializing execution contexts (stack frames) handles function declarations last, meaning that function declarations appear to be hoisted "higher" than var declarations.

This means that if a function declaration and a var with the same identifier are both declared within the same function, the identifier will be associated with the function (and not the var) at the start of execution of the enclosing function.

For let, const and class the identifier will not be initialized until control has moved past the lexical declaration of the variable.

These let, const and class declaration types were added to the language much later in its life (ES 2015).

The language designers chose this new behavior to make JavaScript easier to understand and to avoid subtle bugs that permitting assignment and dereferencing before the lexical point of declaration can introduce.

For this reason, there used to be a best-practice in JavaScript that said variables should be declared at the very top of their enclosing functions.

So in your example code:

1  console.log(a);
2  var a = 4;
   undefined
   undefined

Immediately before execution, when the execution context (or stack frame) for the code is instantiated, a is hoisted to the top of the enclosing scope.

a was declared using var, so on line 1 the dereferencing of a inside console.log(a) is permitted, and the auto-initialized value of undefined is printed to the console.

On line 2, the code will then assign 4 to a(but not print anything out).

If this is run in the browser console, the value returned by the final statement will automatically be printed by the browser.

In this case, the result of var a = 4; is undefined and so a second undefined is printed to the console.

ruffin
  • 16,507
  • 9
  • 88
  • 138
Ben Aston
  • 53,718
  • 65
  • 205
  • 331
  • 1
    "*attempting to use the [let, const or class] identifier before the lexical position of the declaration will throw a ReferenceError*" - no, in fact [these are hoisted as well](https://stackoverflow.com/q/31219420/1048572). They just are not initialised to `undefined`. – Bergi Jan 19 '20 at 23:16
-1

the way this works is that the variable is accessible in the entire program, see the following:

'a' is undefined because it is not declared in the program,

console error

however when I declare a it is now accessible in the entire program. 'a' declared

if I set the value of a, that only occurs AFTER the console log, the order of operations is still intact the only thing that is hoisted is the declaration.

enter image description here

lol I forgot the parenthesis around the 'a' on that last one, not too sure on why quokka still had the expected output, quokka for the win for reading my mind haha

Raphael Castro
  • 907
  • 1
  • 8
  • 26
  • Please add code and data as text ([using code formatting](//stackoverflow.com/editing-help#code)), not images. Images: A) don't allow us to copy-&-paste the code/errors/data for testing; B) don't permit searching based on the code/error/data contents; and [many more reasons](//meta.stackoverflow.com/a/285557). Images should only be used, in addition to text in code format, if having the image adds something significant that is not conveyed by just the text code/error/data. – gre_gor Nov 11 '22 at 11:35