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:
The following code snippet would seem to fit the "by simply assigning it a value" scenario, meaning the variable should be treated as global.
(function(){
console.log(myVar);
//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 myVar
is commented, and undefined when not. I would expect it to generate undefined in both cases, since if myVar
is a global variable (per definition), than javascript's variable hoisting would make it known before reaching console.log(myVar);
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 jsfiddle
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:
var myVar
(or function myVar () { ... }
, or it is listed as a parameter in the function definition). let myVar
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.
Since my comment seemed to help explain it to you, I will turn it into an answer:
Implicit global variable creation (when you don't actually declare it, but just assign to it) is NOT hoisted. The variable creation happens inline at the moment the assignment occurs.
Thus, when you try to read the variable, it does not exist yet and that is an error.
var
or let
declarations are hoisted to the top of their appropriate scope.
All of this should hopefully help explain why you should just run in strict
mode where implicit global creation is illegal and not allowed and triggers an immediate error. It's basically evil. A simple typo misspelling a variable may not trigger an error when you really want it to.
上一篇: 函数参数的默认值?