Javascript Scoping Review - VAR, LET and CONST

JavaScript Scope: var and let and const oh my!

I read up on this years ago - and I do mean years... but I recently flubbed a tech interview because I had forgotten the rules about using the var / let / const keywords when declaring Javascript variables in your code. Lucky for me there's about a million different tutorials online now so this is my refresher tutorial to me (and you) so that I don't mess up any more job interviews.

Full credit for the code below (and the refresher course) to https://www.digitalocean.com/community/tutorials/understanding-variables-scope-hoisting-in-javascript

USAGE: Copy and paste the code samples below into the Javascript console in your browser, then simply hit return on your keyboard to see the code in action.

Some basic rules of Javascript scoping variables using VAR/LET/CONST:
USING VAR
  • Declaring variables with var: var will scope to the function it's declared inside of (local scope), and if not declared inside of a function it's considered a global variable (global scope).
  • var can be hoisted (hoisted means the declaration (but not the initialization) is moved to the top of their scope).
  • var can be reassigned and redeclared.

USING LET
  • Declaring variables with let: let will scope to the block it's declared inside of (think anywhere there are {} characters).
  • let can not be hoisted.
  • let can be reassigned but not redeclared.

USING CONST
  • Declaring variables with const: const will scope to the block it's declared inside of (just like let).
  • const can not be hoisted.
  • const can not be reassigned nor redeclared.

Thinking Out Loud: As I read Javascript code from top to bottom and encounter a variable, I'll say to myself, "here is a var variable declared in the global scope because it's not declared in a function...." or something like, "here is a let variable declared in an if statement, which means since it's in a code block it's only local to the code block and won't overwrite the first variable declaration....". I try to always track in my head the variable name and if it was declared in the global or function/code block space. Then I can look at the next occurrence to see what space it was declared in and if any over writing took place....

VAR: Global scoped when not defined in a function, otherwise scoped to the function (so no "over writing" appears to takes place)

// Initialize a global variable
var species = "human";

function transform() {
  // Initialize a local, function-scoped variable
  var species = "werewolf";
  console.log(species);
}

// Log the global and local variable
console.log(species);  /*"human" because the var "species" is declared as "human" and is in the 
global scope */

transform();  /*this function sets the var "species" inside of transform() as "werewolf", however 
the console.log message immediately after displays "werewolf" because the var declaration is now 
scoped to the function (it doesn't report the global value like the console.log above did....*/

console.log(species); //"human" just like the first console.log due to global scope

VAR: Global scoped when not defined in a function, but if not redeclared inside a function "over writing" will take place

var species = "human";

if (true) {
  // Attempt to create a new variable in a block
  var species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`); /* here is an "if" block, 
  not a function, so when the code runs the "species" var will be overwritten 
  (from human to werewolf) because the "if" block will automatically run. */
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`); /* nothing changed from 
the last time "species" was declared, and last time it was rewritten in an "if" block, so it 
wasn't "protected" in a function block, which is sort of what was observed earlier in the var
declaration example above. */

LET: Global scoped when not defined in a code block { }, otherwise scoped to the code block

var fullMoon = true;

// Initialize a global variable
let species = "human";

if (true) {
  // Initialize a block-scoped variable
  let species = "werewolf";
  console.log(`It is a full moon. Lupin is currently a ${species}.`);
}

console.log(`It is not a full moon. Lupin is currently a ${species}.`);

CONST: Use const to declare variables that won't change ("constant"), so pretty simple compared to the above examples.

BUT THERE ARE RULES: Declare AND assign a value to a const or you'll get an error. Also, you CAN technically change a value for a const variable if the const defines a class and you want to update a value in the property. (See example).
const PIZZA = {
    topping: "mushroom",
    crust: "deep-dish"
}

console.log(PIZZA);

// Modify a property of PIZZA
PIZZA.crust = "crispy";

console.log(PIZZA);

A sample interview question I saw about VAR/LET/CONST

//... more Javascript 'what does this code do' questions
//Test code playing with var inside and outside of functions, testing
//closure and variable declarations
var num = 4;
console.log("num " + num);
function outer() {
  var num = 10;
  function inner() {
    num++;
    var num = 12;
    //let num=13;
    console.log("inner " + num);
  }
  inner();
}
outer();
/*output to screen is 'num 4', then another console.log of 'inner 12'. Var values are only valid 
inside the function they're defined in. If you uncomment the let statement it will fail because 
of the num++ 2 lines above it (let keeps you honest (and within code blocks), var was more flexible 
(but global))
*/

Link your website to this page! Copy and paste the URL below:
http://www.cfsnap.com/javascript/javascript-scoping-review-var-let-const/
Copyright 2019. All Rights Reserved.