When to use `var` or `let`?

I understand the purpose of the const keyword, but what is the reason for the addition of let? Why do many programmers prefer using let rather than var? It seems, to me, that they serve the same purpose.

As far as function scope is concerned, they do, but that is where var falls short of the perfection of let which gives block scope to anything with a block such as a for or while loop, a switch, if…else if…else, etc…, not just functions.

That weakness of var led the working group to find a better way of limiting scope on variables so they aren’t leaking into their parent scope. I suspect that one day soon we will find var deprecated. It cannot be eliminated or legacy code will break, but we can limit our use of the keyword to zero in ES6+ code. let is the keyword of choice for very good reason.

38 Likes

Because BASIC had it right all those years ago right? :smile:

8 Likes

I respect you sir, you have helped me with your comments without knowing. Thank you.

13 Likes

So… is ‘var’ ever necessary these days? Should we, as newly learned, simply not employ it in our code? Good to know it, I realize, in case we are reading older code, but from this day forward?

When we’re just learning is not a good time to be throwing out the bath water, it may just contain the baby. Take in everything and sort it out later, after you’ve gotten your feet wet.

17 Likes

And where do we use const?

const will be applied anywhere we don’t want the value to change, or to protect an object such as an array, object or function.

function foo () {}

The above function can be deleted or overwritten.

const foo = function () {}

The above function can be neither deleted nor overwritten.

7 Likes

Are we going to learn about scope, hoisting and closures in this course?

1 Like

Scope is covered, hoisting may be mentioned, but there is very little if any mention of closures. Scope relates to environment and hoisting relates to declarations made within that environment. Closure is essentially a protected environment such as a function inside a function. The outer function gives the inner function complete closure from the outside.

2 Likes

@mtf
Great! So is there any point for me to learn about scope now? Or should I just wait until I reach this lesson?

Scope is a natural concern, and not a trivial one so getting a firm grasp on what it is and how to prevent polluting outer scope is quite important. There is not a lot to it, when all is said and done.

There are basically three kinds of scope…

  1. global
  2. function
  3. block

We could add in one more, outer scope which is any scope above the current one.

The top of the scope chain is the global scope, the main namespace that contains globals, global constants, most functions, and JavaScript, itself.

Function scope applies to any function constructs which declare variables locally with var, let or const. They cannot be accessed from above. Functions within functions also have their own local scope.

Anything with a block, {} also has local scope when declared with let or const. var does not give block scope, only function scope.

Any variables that are not declared, but merely defined, as in,

a = 42

are automatically hoisted to the top of the scope chain, regardless how nested they may be within functions and blocks. This is known as leakage and what we refer to as ‘polluting the global scope’. Scoping is how we prevent this leakage.

Do read up on scope after beginning to cover it in the lessons. No point jumping ahead.

9 Likes

Thank you for this explanation! I’ll be sure to dive deeper into this subject once I reach this lesson :grinning:

So if I understood correctly, scope is where a variable is accessible

When declaring a variable with the var keyword, it will have a function scope. This means that it will only be accessible within its containing function and its child functions

function foo() {
  var x = 1;

  console.log(x); // 1
  function bar() {
    console.log(x); // 1
  }
}

console.log(x); // Error: x is not defined

When declaring a variable with the let and const keywords, they will have a block scope. This means that they will only be accessible within their containing block

function foo() {
  let x = 1;
  console.log(x); // 1
  if (condition) {
    let y = 2;
    console.log(y); // 2
    console.log(x); // 1
  }
  console.log(y); // Error: y is not defined
}

console.log(x); // Error: x is not defined
2 Likes

Correct. That is the main gist of scope. The scope chain reaches from the lowest scope upwards to the highest scope.

Consider we have a piece of code that polls a certain variable. If that variable is not available in current scope, JS will traverse up the chain to the first scope in which that variable is found, no matter how many links up the chain it needs to go. If the variable is not found by the time global scope is reached, JS returns undefined.

1 Like

Would it not throw an error?

function foo() {
  function bar() {
    console.log(test); // ReferenceError: test is not defined
  }

  bar();
}

foo();

Yes, right you are. My mistake. The ‘undefined variable’ will throw that error.

1 Like

Thank you for your help! I now understand scope clearly

1 Like

This is helpful, however, still confused on how to rewrite var as new variable in legacy code.

I’m sorry, I know this is unrelated, but I want to share this. It is so funny. Copy the code and paste it in a JavaScript thing to show you, then run it. Here is the code: console.log(‘Hello?’);

console.log(’ If anyone receives this code,’);

console.log(‘Sorry, it is probably highly complicated.’);

console.log(‘Well, if you are a random person, which you probably are.’);

console.log(‘Why am I still writing this?’);

console.log(‘There is no point.’);

console.log(‘They will come.’);

console.log(‘He will come.’);

console.log(‘I must go.’);

console.log(‘They are coming.’);

console.log(‘But where fro’);