Understanding let vs. var hoisting [duplicate] - javascript

This question already has answers here:
Are variables declared with let or const hoisted?
(7 answers)
Closed 6 years ago.
With let vs. var I've learned that the major difference is that let variables are scoped to the nearest block and are not hoisted. Also let variables can be reassigned but cannot be redeclared within the same scope. Why then does this code return a "not defined" error?
let x = 10;
if (true) {
console.log(x);
let x = 11;
}
returns:
Uncaught ReferenceError: x is not defined(…)
While:
let x = 10;
if (true) {
console.log(x);
}
logs 10 without an error?

The main difference between var and let is that:
var is hoisted to the wrapping function block.
let is hoisted to the wrapping {} block
The second code sample doesn't have the same reference conflict as the first because you're declaring x prior to referencing it in the following if block.
EDIT To address Pointy's comment below:
You're experiencing the ReferenceError because of the temporal dead zone
If you reference a variable defined by let within the same block before it is defined you will receive this error.
From MDN let Docs
In ECMAScript 2015, let will hoist the variable to the top of the block. However, referencing the variable in the block before the variable declaration results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the declaration is processed.
function do_something() {
console.log(foo); // ReferenceError
let foo = 2;
}

let variables are actually hoisted (within the block). From MDN:
In ECMAScript 2015, let will hoist the variable to the top of the block.

Related

Why JavaScript cannot hoist initialization? [duplicate]

This question already has answers here:
Hoisting variables in JavaScript
(5 answers)
Closed 1 year ago.
I am studying hoisting concept now, but i cannot understand why
hoisting can only work on declaration, not initialization.
declaration O
catName("cat");
function catName(name){
console.log(name) // return cat
}
initialization X
console.log(num); // return undefined
var num;
num = 6;
...why hoisting can only work on declaration, not initialization
It can work with initialization (and in fact, that var variable is initialized — with the value undefined), it's just that hoisting the initializer expression is not defined for var. Hoisting initialization is defined for function declarations: The binding (loosely, variable) for the function is both declared and initialized with the function object:
console.log(example); // Shows the function
function example() {
}
It's just that that's not how var is defined, not least because hoisting the initialization expression (rather than undefined) would be much more complicated than hoisting the initialization of a function identifier, because var initializers can be any arbitrary expression. So instead, var variables are initialized with undefined.
Fast-forward several years and the initialization of let, const, and class aren't hoisted at all (only the declaration), leading us to the Temporal Dead Zone between declaration and initialization during which you can't access them, because that was deemed more useful than hoisting undefined:
console.log(example); // ReferenceError
let example = 42;

Why global let variables not added to window object of browser? [duplicate]

This question already has answers here:
why don't const and let statements get defined on the window object [duplicate]
(2 answers)
Closed 3 years ago.
Consider the code below which I am running in my chrome browser console:
var x = "hello";
let foo = function(){
console.log("hi");
};
console.log(x); // hello
console.log(foo()); //hi
console.log(window.x); // hello
console.log(window.foo()); // Error
If I had used var foo =... instead of let foo = .. then this would have worked. Why ?
This is by design:
let allows you to declare variables that are limited to a scope of a block statement, or expression on which it is used, unlike the var keyword, which defines a variable globally, or locally to an entire function regardless of block scope. The other difference between var and let is that the latter is initialized to a value only when a parser evaluates it (see below).
Just like const the let does not create properties of the window
object when declared globally (in the top-most scope).

Unexpected behaviour of JavaScript with let and var keyword [duplicate]

This question already has answers here:
What is the difference between "let" and "var"?
(39 answers)
Are variables declared with let or const hoisted?
(7 answers)
Closed 4 years ago.
When i am using var keyword to declare a variable then JS engine is assign default value to "message" at creation stage
console.log(message); //undefined
var message = "My message";
but with let keyword
console.log(message); //message is not defined
let message = "My message";
why this unexpected result or it is something changed in ES6?
This is because of the creation of Temporal dead zone with let
let bindings are created at the top of the (block) scope containing the declaration, commonly referred to as "hoisting". Unlike variables declared with var, which will start with the value undefined, let variables are not initialized until their definition is evaluated. Accessing the variable before the initialization results in a ReferenceError. The variable is in a "temporal dead zone" from the start of the block until the initialization is processed.

Javascript lambda function does not see variable from parent scope [duplicate]

This question already has answers here:
What is the scope of variables in JavaScript?
(27 answers)
Closed 7 years ago.
In the code below
var x = 1;
(function () {
console.log(x);
var x = 2;
}());
Why is it that when console.log(x), x is undefined?
Variable hoisting. The actual code is executed like this.
var x = 1;
(function() {
var x; // x = undefined
console.log(x);
x = 2;
})();
Edit: On Mr Lister's advice, a bit on variable hoisting. From MDN (https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Statements/var):
"Variable declarations, wherever they occur, are processed before any code is executed. The scope of a variable declared with var is its current execution context, which is either the enclosing function or, for variables declared outside any function, global."
Because of the compiler, even if you initiate a var down below the code, the compiler send it to the top, just like var x;, so it first initiate as undefined "x" before running console.log, that's why is such a good practice to initate all vars you're going to use first thing in the function, so these mistakes won't happen.

Does an if statement create a local scope? [duplicate]

This question already has answers here:
javascript variable scope in the IF statement
(5 answers)
Closed 6 years ago.
I am currently reading through some javascript tutorials and I came upon this bit of example code from here: http://www.w3schools.com/js/js_if_else.asp
if (hour < 18) {
greeting = "Good day";
}
In this example, the greeting variable is not prefixed with a var statement. Now I looked up what this means, and my understanding is that it causes java script to look to a higher scope, if no variable is discovered by the global scope it creates it.
So is this tutorial doing this because the if statement's block is a local environment? If so does that mean that if I were to have some code that looked like this:
if (condition){var x=10};
else {var x=5};
then there would still be no global variable x for me to call?
In JavaScript (ES5), an if statement does not create a local scope when declaring with var. Local scope is created with a function.
W3Schools is notorious for using bad practices in their code samples, and you've found one example of this. They are creating a globally-scoped variable.
Blocks will only create a local scope for variables declared with the new let keyword. If you're using an older version of JavaScript, or if you're using the var keyword, then the variable is scoped to the innermost function that the variable is declared in.
Variables declared via var outside of any function are scoped to the window (global) scope.
{
var x = "hello world";
}
document.getElementById("var-value").innerHTML = x;
<span id="var-value"></span>
In the above snippet, if you replaced var with let, it would produce an error because x is undefined.
{
let x = "hello world";
}
document.getElementById("var-value").innerHTML = x;
<span id="var-value"></span>
You would be able to get the value of x outside of the if..else. This is due to JavaScript having function scope rather than block. I created a JSFiddle of your example, which can be found at https://jsfiddle.net/h4gjb8mt/
Example:
var condition = true;
if (condition) {
var x=10;
}
else {
var x=5;
}
console.log(x);

Categories

Resources