Veverke Veverke - 5 months ago 9x
Javascript Question

Javascript hoisting and variable assignment (with no declaration)

Looking at MDN's introduction to JavaScript, Grammar and Types section - one reads:

Declaring variables

You can declare a variable in three ways:

  • With the keyword var. For example, var x = 42. This syntax can be used to declare both local and global variables.

  • By simply assigning it a value. For example, x = 42. This always declares a global variable. It generates a strict JavaScript
    warning. You shouldn't use this variant.

  • With the keyword let. For example, let y = 13. This syntax can be used to declare a block scope local variable. See Variable scope

The following code snippet would seem to fit the "by simply assigning it a value" scenario, meaning the variable should be treated as global.

//the following will throw a ReferenceException error
//myVar = 10;

//the following will not, and I can understand it following the defintion of the behavior of using `var` keyword
//var myVar = 10;

But running the code will generate a ReferenceException when
is commented, and undefined when not. I would expect it to generate undefined in both cases, since if
is a global variable (per definition), than javascript's variable hoisting would make it known before reaching

What is the explanation behind such behavior ? (the behavior I described is what I get when trying it in my firefox's console, but running it in
will not throw an error).

Are self-executing functions an exception to hoisting ?


the "by simply assigning it a value" scenario

You are reading the value, not assigning it

if myVar is a global variable (per definition),

It isn't.

myVar is:

  • a variable scoped to the function if the function contains var myVar (or function myVar () { ... }, or it is listed as a parameter in the function definition).
  • a variable scoped to the block if the block contains let myVar
  • a global variable if a value has been assigned to it previously and neither of the above conditions are true.

Since you haven't assigned a value, it isn't a global. Since none of the above conditions are true, it isn't any kind of variable, so you get a reference error.

Regarding your comment:

I left my var when I meant var in the scenario I am trying to depict. Updated question.

… and the edit to which you refer:

Commented out code is not evaluated. Having a comment that uses the keyword var doesn't do anything.

Regarding your further edits.

You get a reference error if you try to read a variable before it has been declared.

var statements (and function declarations) are hoisted so a variable declared with those methods can be read anywhere in the function.

Assignments are not hoisted. A global variable created implicitly by assignment (which is generally not considered to be best practise and is banned in strict mode) can't be read before the value is assigned.