So I came across something very odd while working on a javascript project just now and here's a boiled down example of the situation I'm confused about:
function doSomething() {
for(var d = 0;d < 10;d++) {
var shouldBePrivate = 5;
}
for(var d = 0;d < 10;d++) {
console.log(shouldBePrivate);
}
}
When you call doSomething() the shouldBePrivate variable is accessible in the 2nd for loop.
Shouldn't that not be possible?
Scope in JavaScript refers to the current context of code, which determines the accessibility of variables to JavaScript. The two types of scope are local and global: Global variables are those declared outside of a block. Local variables are those declared inside of a block.
No, You can't access let variables outside the block, if you really want to access, declare it outside, which is common scope.
Block Scope Before ES6 (2015), JavaScript had only Global Scope and Function Scope. ES6 introduced two important new JavaScript keywords: let and const . These two keywords provide Block Scope in JavaScript.
JavaScript variables have only two scopes. Global Variables − A global variable has global scope which means it can be defined anywhere in your JavaScript code. Local Variables − A local variable will be visible only within a function where it is defined. Function parameters are always local to that function.
All local variables in javascript have function scope and not the block scope (atleast before ECMAScript 2015
). Which means that declared variables inside the function , available for whole function.
What you are referring is block scope. Unfortunately noblock scope in Javascript till ECMA2015
. From ECMAScript 2015
, you can declare your variables with let
which can be referred only with in the block and they die as soon as you come out of that block.
MDN docs says (with examples)
Block Scoping Rules
With var
Variables declared with var do not have block scope. Variables introduced with a block are scoped to the containing function or script, and the effects of setting them persist beyond the block itself. In other words, block statements do not introduce a scope. Although "standalone" blocks are valid syntax, you do not want to use standalone blocks in JavaScript, because they don't do what you think they do, if you think they do anything like such blocks in C or Java. For
example:
var x = 1;
{
var x = 2;
}
console.log(x); // logs 2
This logs 2 because the var x statement within the block is in the same scope as the var x statement before the block. In C or Java, the equivalent code would have outputted 1.
With let and const
By contrast, identifiers declared with let and const do have block scope:
let x = 1;
{
let x = 2;
}
console.log(x); // logs 1
The x = 2 is limited in scope to the block in which it was defined.
You've stumbled upon something called hoisting. Because all variables are scoped to their containing function, var
statements are internally moved to the top of the function.
That means that the interpreter will actually be running this code:
function doSomething() {
var shouldBePrivate;
var d;
for(d = 0;d < 10;d++) {
shouldBePrivate = 5;
}
for(d = 0;d < 10;d++) {
// now it's easy to see why this works
console.log(shouldBePrivate);
}
}
As of ES2015, you can use the let
keyword instead of var
which is lexically scoped - i.e. scoped within blocks, meaning that let shouldBePrivate = 5;
will not exist outside the first loop.
function doSomething() {
for(let d = 0;d < 10;d++) {
let shouldBePrivate = 5;
}
for(let d = 0;d < 10;d++) {
// Reference Error for shouldBePrivate
console.log(shouldBePrivate);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With