• Skip to primary navigation
  • Skip to main content
  • Skip to primary sidebar

I Like Kill Nerds

The blog of Australian Front End / Aurelia Javascript Developer & brewing aficionado Dwayne Charrington // Aurelia.io Core Team member.

  • Home
  • Aurelia 2
  • Aurelia 1
  • About
  • Aurelia 2 Consulting/Freelance Work

Const or Let: Let’s Talk Javascript

Javascript · July 21, 2016

Two of my favourite additions to ECMAScript 2015 were the const and let keywords. Sadly, I see them being misused quite often on many public repositories and even in some projects I have worked on.

Const (constants)

If Javascript is not the first language you have worked with, then you will be familiar with constants in other languages like Java or PHP. A constant is an immutable variable. An immutable variable means its value will always be the same, it never changes (hence why they’re called constants). Also worthy of note is like let block scoped variables, constants are block scoped as well.

But developers are using constants for the wrong reasons. Just because a constant is a read only reference to a value does not mean the value inside of it is immutable. Constants only protect you from reassigning the value, not mutating the value within, such as; Map, Array or Object.

If you come across const myConfig = {myProp: 'somevalue'} one might assume that this would never be allowed to change, but that is not how Javascript works. You can’t assign a new object or change the value, but you can change the properties of the object in the constant. This is because the value inside of the constant is not immutable.

This will work:

const myConfig = {
    someProp: 'myvalue'
};

myConfig.someProp = 'fkjsdklfjslkd';
myConfig.aNewProp = 'I did not exist when initially defined';

This will not work:

const myConfig = {
    someProp: 'myvalue'
};

myConfig = {}; // Cannot reassign a constant value

However, you can make an object immutable using Object.freeze which will make mutating the object inside of our constant impossible. However, if your object contains objects of its own, those will not be frozen, so you will need to use Object.freeze to make those immutable as well.

If we take that first example and use Object.freeze we get our desired outcome of making the object immutable as well.

const myConfig = {
    someProp: 'myvalue'
};

Object.freeze(myConfig);

// Original value remains intact
myConfig.someProp = 'fkjsdklfjslkd';

// New property will not be added
myConfig.aNewProp = 'I did not exist when initially defined';

console.log(Object.isFrozen(myConfig)); // true

My personal use of constants is for avoiding the use of magic literals in my code. See below for an example where I am wanting to see if a user has pressed the escape key on their keyboard.

I know that the escape key text is always going to be “Escape” in supported browsers or browsers still using “keyCode” it will always be 27. These values will always be the same, so I define them and use those when comparing. It makes my code way more readable.

const ESC_KEY = 'Escape';
const ESC_KEY_CODE = 27;

document.addEventListener('keydown', evt => {
    let isEscape = false;

    if ('key' in evt) {
        isEscape = evt.key === ESC_KEY;
    } else {
        isEscape = evt.keyCode === ESC_KEY_CODE;
    }

    if (isEscape) {
        window.alert('Escape key pressed');
    }
} 
});

The bottom line with constants is to be careful that you don’t fall into a false sense of security. They don’t necessarily protect your value from being mutated, especially if used with objects, arrays and so on.

If you need to use an object with constant for whatever reason, make sure you freeze it (and any child objects) to make it immutable.

Let (block scoped variables)

By default standard var variables in Javascript are function scoped. In comparison to other languages like Java, variables are block scoped.

Function scoped variables have been causing headaches for us front-end developers since the dawn of time because they essentially allow you to clobber any existing values or spam your functions with additional variables.

My favourite thing to use let for is loops. A standard for..loop you might be writing might look something like this:

var i = 100; // This is a bit contrived
var array = [1, 2, 3];
for (var i = 0, len = array.length; i < len; i++) {
    console.log(i);
    console.log('Loop: ', array[i]);
}

console.log(i); // This will print 3

Let’s clear a couple of things up first. I don’t define an index variable like that, but imagine you were using a variable with the name increment instead and it was defined at the top of your function and used by other parts of your code.

Then you come along and write a for..loop, you don’t realise you already have a increment variable and you end up overwriting the existing variable. All of a sudden your original value is gone.

Enter block scoped variables

var i = 100;

var array = [1, 2, 3];
for (let i = 0, len = array.length; i < len; i++) {
    console.log(i);
    console.log('Loop: ', array[i]);
}

console.log(i); // This will print 100

You already have a variable called i define and hoisted to the top of your function. Then you define a loop, use let with the same name and the original value remains intact. Why? Because block scoped variables constrain themselves to the nearest open/closing curly’s {} therefore this i variable is only accessible inside of the loop.

Another example is declaring variables inside of if statements:

let myNumber = 500;

if (myNumber === 500) {
    let myNumber = 1000;
    console.log(myNumber); // Now 1000
}

console.log(myNumber); // Keepin' it 500

I generally try and use block scoped variables as much as I can, it saves me a lot of problems. Scoping variables to blocks also makes the intent of your code a whole lot more clearer and easier to read code as well.

Conclusion

Both const and let are blocked scoped. You should be using const for immutable values; text labels, numbers and anything that never needs to change. You should be using let to ensure that you are limiting the scope of specific variables where they are being used and avoiding the use of global variables or function scoped variables almost entirely.

Dwayne

Leave a Reply Cancel reply

3 Comments
Oldest
Newest Most Voted
Inline Feedbacks
View all comments
Michael
Michael
6 years ago

even if an object is const without being frozen, it communicates to developers reading the code (just not the machine executing it) what the intention was, which is how we’ve used it – we’re aware that the values are mutable, but going to the extra effort of freezing it (perhaps recursively) wasn’t worth the effort for us.

0
Chris
Chris
6 years ago

I know that some folks like using the “const” keyword to make JavaScript work in a more “functional” programming way. It’s definitely good if they understand, as you mentioned, that these can be modified if they are objects.

As for the “let” keyword, I only hope it doesn’t make JS developers feel like they now have a license to write code with high levels of cyclomatic complexity. In my personal opinion, having lots of nested blocks of code in a function generally indicates that they are not keeping things simple enough. It’s good that the “let” function helps protect them a bit from the pitfalls of this practice, but if they think it means that they don’t have to worry about it any more, then I’m not sure how much it’s helping.

0
Kevmeister68
Kevmeister68
6 years ago

Coming from a C++/C# background, and now using TypeScript rather than plain-vanilla JS, our strategy is simple. We *never* use var. Ever. It’s effectively banned from our coding standards.

The let keyword gives us semantics we are more used to. That’s not to say this approach is for everyone, but when I read about variable hosting in JavaScript it was definitely a “what the!” moment and I thought “bugger that!”, I’m not going there.

0

Primary Sidebar

Popular

  • I Joined Truth Social Using a VPN and Editing Some HTML to Bypass the Phone Verification
  • Testing Event Listeners In Jest (Without Using A Library)
  • How To Get The Hash of A File In Node.js
  • Thoughts on the Flipper Zero
  • Waiting for an Element to Exist With JavaScript
  • Handling Errors with the Fetch API
  • How To Get Last 4 Digits of A Credit Card Number in Javascript
  • How To Paginate An Array In Javascript
  • Wild Natural Deodorant Review
  • How To Install Eufy Security Cameras Without Drilling or Using Screws

Recent Comments

  • CJ on Microsoft Modern Wireless Headset Review
  • Dwayne on Microsoft Modern Wireless Headset Review
  • CJ on Microsoft Modern Wireless Headset Review
  • john on Microsoft Modern Wireless Headset Review
  • Dwayne on Why You Should Be Using globalThis Instead of Window In Your Javascript Code

Copyright © 2023 · Dwayne Charrington · Log in

wpDiscuz