Are let and const faster than var in JavaScript?

ES6 introduced let and const as alternatives to var for declaring variables in JavaScript. Because const is not hoisted to the top of the execution context in the same way var is, const should be faster, right?

Dr. Derek Austin 🥳
Jan 19 · 10 min read
Photo by Mg Cthu on Unsplash | There are no affiliate links in this article.

Execution context and hoisting

The first lecture in Tyler McGinnis’s Advanced JavaScript course covers execution context and hoisting, and it got me wondering about instantiating variables using var and const in JavaScript.

After the lecture, I was left thinking that the JavaScript keyword var might be slower than the keyword const, because var needs to be hoisted.

Perhaps that extra step in the execution context hurts performance. If so, we would also expect to find that let is slower than var.

(If you’re not sure about the difference between each of these keywords for declaring variables, I’ve previously compared let, var, and const).

There’s evidence that many modern JavaScript features are slower than older JavaScript code. After all, ES6 (ECMAScript 6) was released in 2015 (and thus is also called ES2015). Prior to that, we were all using ES5 — and many developers still do in order to support older browsers.

Kevin Decker has an amazing chart comparing the performance of ES6 features to ES5 baselines. You may be familiar with for...of loops being slower than old-fashioned for loops in JavaScript, for example:

Screenshot by the author of http://incaseofstairs.com/six-speed/, a site by Kevin Decker

Newer browser versions have generally reduced but not eliminated the performance gap that exists for ES6 features.

The idea that const is actually slower than var because of hoisting seems plausible, so I decided to test the hypothesis myself.

Photo by Vittorio Zamboni on Unsplash

Wait, what is hoisting?

Hoisting is the part of the creation phase of the JavaScript execution context where variable declarations are assigned undefined .

In creating the execution context, the JavaScript interpreter assigns variable declarations a default value of undefined while placing any function declarations in memory. The variable references then already exist when they’re used later.

Basically, the JavaScript interpreter looks for var and function keywords and “hoists” those variables by assigning them the value of undefined.

But does this mean that there is an extra step needed when using var to declare a variable instead of using the ES6 keywords let or const? Shouldn’t that make let and const slower than var?

Photo by Sean Pierce on Unsplash

Why const could be faster

It appears that using const would inherently make code a little faster, because it seems to reduce the amount of hoisting necessary.

Take the following, basic example:

var greeting = "Hello world!"

When executed using var, the code is interpreted in the following way because of hoisting (though no code is actually moved by the interpreter):

var greeting // undefined
greeting = "Hello world!"

So, it stands to reason that quite possibly the following might be faster:

const greeting = "Hello world!"

While it appears trivial, if let and const are actually faster, then that would be a strong argument for consistently using them. We would also want to actively refactor old code currently using var.

Photo by Łukasz Łada on Unsplash

Hoisting works similarly for functions

In the case of creating a function, hoisting works similarly in JavaScript. When using the function keyword, the code is treated like var:

function reverseString(string) { return string.split("").reverse().join("") }

Again, the function declaration is hoisted, effectively creating:

var reverseString
reverseString = function (string) { return string.split("").reverse().join("") }

Compare that to using a const and an anonymous function declared with the arrow syntax:

const reverseString = (string) => string.split("").reverse().join("")

Again, it may not make any difference at all, but doesn’t it seem that fewer steps for the compiler would mean faster performance?

Photo by Ruston Youngblood on Unsplash

The test results

To find out if the ES6 keyword const is faster than using var, I ran test cases using jsPerf, a free JavaScript performance testing tool that runs in the browser.

Author’s note: Unfortunately, jsPerf has gone down.

Users interested in micro-benchmarking using their own setups are advised to try https://jsbench.me/ or https://jsben.ch/ as alternatives.

I reasoned that only using const would make for a clearer test. Intuitively, it seemed that constant declarations would somehow be faster than variable declarations, so const would be faster than var.

Since hoisting is used for both var variables and function functions, I wanted to test the performance of function declarations as well.

Depending on the results, I would go back to compare let and var, taking a look at any found differences in more detail.

Test 1 —Variables only

Screenshot by the author of jsPerf.com

There was no difference in performance when instantiating five variables, including a string concatenation using backtick literals.

We see right off the bat that const and var have identical performance, at least on my Windows 7 machine running Firefox (x64).

Photo by Hide Obara on Unsplash

Test 2 — functions only

Screenshot by the author of jsPerf.com (The results are ~50% slower than Test 1.)

Functions also showed identical performance, as we can see for the reverseString function in the above test case.

Just like we saw for variables, there was no difference in performance for functions declared as const variables using the arrow syntax compared to those declared using the traditional function keyword syntax.

Photo by Mantas Hesthaven on Unsplash

Third — variables and function

Screenshot by the author of jsPerf.com (The results are ~50% slower than Test 1.)

Combining both code snippets produced the same result: there was no difference in performance between using var and const. I decided not to test let in detail, since the performance was identical.

A valid criticism of the above test cases is that calling console.log() slows down the code execution, possibly hiding any effects of hoisting.

Indeed, tests 2 and 3 each have a pair of console.log() statements, instead of just the single console.log() call in test 1. And, as we might expect, tests 2 and 3 run about 50% slower than test 1.

If the performance difference between const vs. var was large enough to worry about, I would think it would still show up. However, I also ran similar tests without console.log() using Chrome, and the results were the same: there was no difference between const and var.

That said, you may want to remove console.log() statements when you’re conducting your own microperformance testing.

Photo by Saffu on Unsplash

What it means

Some newer ECMAScript features are definitely faster than previous implementations, like the .padStart() and .padEnd() string padding methods that were added in ES2018. My testing on string padding performance showed .padStart() was actually 10x faster.

Other newer features are slower than the older versions, like the aforementioned for...of loops. For variable declaration at least, there is no performance boost changing from var (ES5) to const (ES6).

Under the hood, JavaScript is treating var, let, and const variables the same, except for their important differences in lexical scope (that I explained previously in my article in JavaScript in Plain English).

Unlike the padding algorithms noted above, which deliver a performance benefit, there’s no performance benefit (or penalty) for choosing to use let and const instead of var and function.

The execution context underlying how the JavaScript interpreter runs the code is basically the same when you use var compared to when you use let and const. That results in the same execution speed.

Photo by Outsite Co on Unsplash

Comparing const to compiling

The reason const is not faster than var is that const is not really a new feature, as JavaScript of course had variables all along. A minor change in lexical scope really doesn’t affect anything regarding performance, even with hoisting (or the lack there-of).

Meanwhile, a brand-new feature like string padding has the potential to be much faster than the old way of doing things.

To put it in context, let’s compare compiling vs. polyfilling:

  • Using a different keyword like let or const still instantiates a new variable in JavaScript’s execution context in much the same way that var does (and thus const could be compiled with Babel).
  • Other features like string padding include new algorithms that may have better underlying performance (but string padding would need to be polyfilled to be compatible with older browsers).

Generally, compiling will be just as fast, but polyfilling may be slower.

To make a prediction about the speed of a new ECMAScript feature, you can think about it in terms of compiling and polyfilling:

  1. The newer feature is faster if it replaces a polyfill with native code, as with string padding. It’s like removing a polyfill.
  2. The older feature is faster if the newer feature adds extra code under the hood, as with for...of loops. It’s like adding a polyfill.
  3. The features will be the same speed if there is no change in the amount of code to process. It’s like Babel compiling let to var — no code was added, so the performance should be the same.

The last reason is exactly why I found ES6 backtick literals aren’t slower; they’re the same speed as ES5 string concatenation.

Photo by Manuel Inglez on Unsplash

Why to use const anyway

There are plenty of reasons to use let and const instead of var, but worrying about performance hits from hoisting is not one of them.

These are the 4 advantages of let and const identified by Maya Shavin in Front End Weekly:

Avoid polluting our global object with unnecessary properties.

Avoid hidden 🐛 — such as modifying a constant value by mistake, updating wrong variables which are in different scope block but declared with same name, etc…

Avoid unnecessary hoisting.

Add more restrictions to force our code [to be] more reliable, organized and easier to read

Another great reason to use const is that using const instead of var tells the next developer that the given variable is meant to be a constant. Other than SCREEN_CASE, there’s not a great way to do that in JavaScript.

Photo by Alan Jones on Unsplash

Conclusion: let and var walk into a bar…

Variables declared with var and functions declared with function are hoisted to the top of the execution context and assigned a value of undefined before any code is interpreted. In comparison, the ES6 keywords let and const are not hoisted.

Compared to using const, there is no performance difference in declaring variables or functions with var and function, at least in my microperformance testing in a modern web browser.

Hoisting does not slow JavaScript down in any way — and why should it? It’s one of the oldest concepts in JavaScript (though the term hoisting itself didn’t become part of the ECMASCript specification until ES6).

Nevertheless, using let and const is generally recommended to limit scope and mutability and therefore minimize bugs.

That being said, don’t forget that objects (including arrays) declared using const can have their contents changed. That’s the reason we need to deep copy nested objects and arrays, though a shallow copy of an array works great if the array doesn’t contain any other arrays or objects.

While microperformance testing is often trivial (for...of loops being 1.6x slower doesn’t matter for 99% of codebases), I think it’s a useful way of thinking critically about how JavaScript actually works. And developing critical thinking skills about the programming languages we use every day is something that helps all of us improve as developers.

If you enjoyed this article, you may enjoy reading about my surprising results when using the ... spread operator to find the smallest and largest numbers in an array. I definitely wasn’t expecting what I found:

I’ve included additional resources below to help you master the essential JavaScript concepts of scope, execution context, and hoisting.

Happy coding! 😁👩‍💻💻👨‍💻🧠

Photo by Johannes Plenio on Unsplash

Further reading

  • Gemhar Rafi delivers one of the clearest explanations of let, var, and const that I’ve ever read in his piece on Dev.to:
Photo by OC Gonzalez on Unsplash

Coding at Dawn

Laid-back programming + relaxing photography

Dr. Derek Austin 🥳

Written by

🤓 The physical therapist who writes JavaScript 💪 Web Developer 😎 Mentor 🧠 DPT 😄 SEO Expert 😁 React 😆 Jamstack 💬 Ask me anything 👉 DoctorDerek.com 👈

Coding at Dawn

Laid-back programming + relaxing photography

Dr. Derek Austin 🥳

Written by

🤓 The physical therapist who writes JavaScript 💪 Web Developer 😎 Mentor 🧠 DPT 😄 SEO Expert 😁 React 😆 Jamstack 💬 Ask me anything 👉 DoctorDerek.com 👈

Coding at Dawn

Laid-back programming + relaxing photography

Medium is an open platform where 170 million readers come to find insightful and dynamic thinking. Here, expert and undiscovered voices alike dive into the heart of any topic and bring new ideas to the surface. Learn more

Follow the writers, publications, and topics that matter to you, and you’ll see them on your homepage and in your inbox. Explore

If you have a story to tell, knowledge to share, or a perspective to offer — welcome home. It’s easy and free to post your thinking on any topic. Write on Medium

Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store