In ES2015(ES6) and above, the advice given for variable declaration is “If possible, use const. Only use let if you know its value needs to change and never ever use var. (You can always go back and change a const to a let if it later turns out you need to change its value.)

Lets consider a common situation of pre ES6 frontend js code that you wrote in one of your web-application

1
var a=1; var b=2; var c=3; console.log(window.a,window.b,window.c);

and you refactoring it to ES6

1
const a=1; const b=2; const c=3; console.log(window.a,window.b,window.c);

The results are not what you expect and voila you learn something new today.
oops
Now consider this code, you can run this in node REPL or the browser console or run it as a script:

Example 1:

1
2
var a=1; var b=2; var c=3; console.log(this.a,this.b,this.c);
// 1 2 3

The same above code substitue the this with the window object when running in browser console, this is for better clarity( what clarity, you will know in a bit 😉 ):

Example 2:

1
2
var a=1; var b=2; var c=3; console.log(window.a,window.b,window.c);
// 1 2 3

Now being the good developer you are, if you refactor the code and heed to the advice of never using var, you are in for surprises:

Example 3:

1
2
3
4
const a=1; const b=2; const c=3; console.log(window.a,window.b,window.c);
// undefined undefined undefined
const a=1; let b=2; var c=3; console.log(a,b,c);
// 1 2 3

Example 4:

1
2
const a=1; let b=2; var c=3; console.log(window.a,window.b,window.c);
// undefined undefined 3

wait!! what’s happening here. Let’s break it down:

The common term used when describing the scope availability of let,const is that they are blocked scope and var is global scope or the scope enclosed in the given function.

The precise way of describing this concept is let and const declarations define variables that are scoped to the running execution context‘s LexicalEnvironment, and var are scoped in the VariableEnvironment.

Now going back to the Example 4 the variables a and b are not scoped to the window object but they are scoped to the LexicalEnvironment of the current execution context, now is there a way to get that current execution context and see what all it has? If you know a way, please enlighten me.

Today(2020-06-18) while debugging a cross browser issue, I found out that Google Chrome V83 (My primary browser is firefox and it does not have this yet) lists a scope property [[Scopes]] when viewing the object in the Developer tools. It has a script scope and a Global scope, this clearly indicates what is available on which scope. The mystery of running execution context’s scope is solved.
For Example, type the following in the Chrome Dev Tools and check the [[Scopes]] property :

1
2
3
const a=1; let b=2; var c=3;
function f(){}
console.dir(f);

const let var scope

“Any fool can know. The point is to understand.”
-Albert Einstein

Leave a Reply

Your email address will not be published. Required fields are marked *

You may use these HTML tags and attributes:

<a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <s> <strike> <strong>