completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Variables: let, const & var

Learn how JavaScript stores values with let and const, why mutation is different from reassignment, how to choose legal names, and why new code avoids var.

By the end, you can
  • 01
    Choose let or constMake variables, and know when a name can get a new value.
  • 02
    Tell a new value from a change insideExplain why a const array can still get new items.
  • 03
    Spot the problems with varKnow how var leaks out of blocks, exists before its line runs, allows the same name twice, and adds to window.

A variable is a name for a value

A variable is a name for a value. A value is one piece of data, like the number 0 or the text "Asha". When you write let score = 0;, JavaScript makes a variable named score and puts the number 0 in it. Later, your code can use the name score to get the number back.

let score = 0. A box named score holds a card with the value 0. The name is on the front of the box. The value is inside.let score = 0;0scorethe namethe value
let score = 0; makes a box named score and puts the value 0 in it. Later, your code uses the name to get the value back.

You saw a small version of this in the Why JavaScript? lesson. A Like button kept its count in a variable called likes. It used = to store each new count, and console.log to print messages. This lesson goes through the same idea slowly, one rule at a time.

The main rule

Use const for most variables. Use let when the same name needs a new value later. Don't use var in new code.

A name that keeps its value, and a count that changesPop out in the code editor (opens in a new tab)JavaScript
const userName = "Asha";
let teaCount = 1;
teaCount = teaCount + 1;
console.log(userName);
console.log(teaCount);

Line 1 uses const to make a variable named userName. It holds the text "Asha", and it will keep that value. Line 2 uses let to make a counter, teaCount, and starts it at 1. Line 3 works out teaCount + 1, which is 2, and puts 2 into teaCount. Lines 4 and 5 print Asha and 2.

Real-life analogyA variable is a labeled box

Picture a shelf full of boxes. Each box has a label, like "score". You don't need to describe what is inside each time. You just say the label, and everyone knows which box you mean.

In real life: The label on a box
In JavaScript: The variable name, such as score
In real life: The thing inside the box
In JavaScript: The value, such as 0 or "Ada"
In real life: Reading the label to find the box
In JavaScript: Using the variable's name in your code
In real life: Taking the old thing out and putting a new thing in
In JavaScript: Giving a let variable a new value

Making a variable is called declaring it. You declare a variable with a keyword: a word that has a special job in JavaScript. This lesson covers three of these keywords:

  • let and const are the modern ones. You will use them every day.
  • var is the old one. You need to be able to read it in older code, but you should almost never write it.

let and const: can the name get a new value?

STEP THROUGH

To declare a variable, you pick a keyword and then a name. You can give it its first value on the same line. Giving a variable its first value is called initializing it.

  • const appName = "CompleteFrontend"; makes a name that keeps the same value.
  • let score = 0; makes a name that can get a new value later.

Giving a variable that already exists a new value is called reassignment. You do it with the = sign. Read a line with = from right to left:

  1. First, JavaScript works out the right side.
  2. Then it puts the result into the name on the left.
A let variable can start with no valuePop out in the code editor (opens in a new tab)JavaScript
let message;
console.log(message);
message = "Ready";
console.log(message);

Line 1 makes message but gives it no value. So it starts as undefined, which is JavaScript's way of saying "no value yet". Line 2 prints undefined. Line 3 puts the text "Ready" into message, and line 4 prints Ready. A const must get its value on the same line, because it can never get one later.

Step through: giving score a new value
Step 0 of 5Ready
Your turn: follow the blue line

Guess the value printed on line 4. Step through the let version, then switch to const and see where the real error happens.

Running in
  1. script
Next: line 1
score = 10;score = score + 5;console.log(score);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Change line 1: make score with let or const?

Changing this starts the replay again. Guess what line 2 does before you press Step.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.

Step through the let version first. score starts at 0, then becomes 10, then becomes 15. Now switch to const. Line 1 still works. Line 2 throws a real TypeError, because a const name can't get a new value. An error is JavaScript's way of saying "I can't do this". It stops the program. A TypeError is one kind of error.

Left: with let, score = 10 puts 10 in the box named score. Right: with const, the same line throws a TypeError, and the box still holds 0.let score = 0;score = 10;1010scorescore is now 10const score = 0;score = 10;100scoreTypeError
The same line, score = 10;, in both. With let, the box gets the new value. With const, JavaScript throws a TypeError, and score keeps 0.
This error helps you

If a const gets a new value, JavaScript throws this error. It means one of two things. Maybe the variable should have been made with let. Or maybe your code is changing a value by mistake, when that value should stay the same.

A new value vs a change inside

INTERACTIVE

Some values hold other values inside them:

  • An array is a list of values, like ["pen", "book"].
  • An object holds values that each have a name, like { theme: "dark" }.

With arrays and objects, const surprises many people. That's because there are two different ways to change things:

  • Reassignment gives the name a whole new value, like cart = ["book"]. const blocks this.
  • Mutation changes what is inside the value the name already has, like cart.push("book"). const allows this. push adds an item to the end of an array.

So const keeps the name on the same array or object. It does not lock what is inside.

Real-life analogyA const label is glued to the toolbox

Imagine a label glued to a toolbox. You can't peel it off and stick it on another toolbox. But you can still open the toolbox and move the tools around inside.

In real life: A label glued to one toolbox
In JavaScript: A const name that stays on one array or object
In real life: Moving the label to a new toolbox
In JavaScript: Reassignment, which const blocks
In real life: Putting a screwdriver in the same toolbox
In JavaScript: Mutation, like cart.push("book")
In real life: Two labels on the same toolbox
In JavaScript: Two variables for one array

In the next replay, you choose what line 2 does. It can add an item to the array with push. Or it can try to give cart a whole new array. Guess which one const allows before you press Step.

Change the inside, or replace the array?
Step 0 of 6Ready
Your turn: follow the blue line

Guess whether const allows line 2. Step through mutation first, then switch to reassignment.

Running in
  1. script
Next: line 1
cart.push("book");console.log(cart);const other = cart;other.push("ink");console.log(cart);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Change line 2: add an item, or give cart a new array?

Both versions use const cart. Only one keeps the name on the same array.

A guided replay recorded from real JavaScript calls, not an engine debugger. Step follows executed statements; Back reviews a snapshot. Reset starts a fresh run.
Left: cart.push of book adds a book card to the same cart, which now holds pen and book. Right: cart = a new array throws a TypeError, and the cart still holds only pen.cart.push("book");penbookcartsame array, new itemcart = ["book"];pencartTypeError
Both start with const cart = ["pen"];. Adding an item changes what is inside the same array, so const allows it. Giving cart a whole new array is not allowed.
A const object can change insidePop out in the code editor (opens in a new tab)JavaScript
const settings = { theme: "dark" };
settings.theme = "light";
console.log(settings.theme);

The name settings stays on one object the whole time. Line 2 changes the theme value inside that object, so line 3 prints light. That is mutation, so const allows it. Giving settings a whole new object would be reassignment, and const would block it.

One more thing happens in the replay. Line 4, const other = cart;, does not copy the array. It gives the same array a second name. So when line 5 runs other.push("ink"), cart shows the ink too.

The array named cart holds pen, book, and ink. A tag named other points to the same cart. There is only one array.const other = cart;othera second namepenbookinkcart
const other = cart; doesn't make a copy. It ties a second name to the same array. So the ink added through other shows up in cart too.

Rules for names, and words you can't use

SORTER

A variable's name is also called an identifier. A name can use:

  • letters, including letters like é, so café is a real JavaScript name
  • digits, but not as the first character
  • the signs $ and _

A name can't have a space or a hyphen (-) in it.

Names JavaScript allowsPop out in the code editor (opens in a new tab)JavaScript
const userName = "Ada";const firstName2 = "Grace";const $price = 20;const _count = 3;const café = "coffee";console.log(userName, firstName2, $price, _count, café);
Capital letters make a different namePop out in the code editor (opens in a new tab)JavaScript
const userName = "Asha";
const username = "Lin";
console.log(userName);
console.log(username);

userName and username differ by one capital letter. To JavaScript, they are two different names. So the example prints Asha and then Lin. Write each name the same way every time. If you change one capital letter, JavaScript looks for a different variable.

Allowed doesn't always mean good. $price is allowed, but many teams keep $ for special uses by their tools. In Stage 1 you met camelCase: words joined together, with a capital letter at the start of each new word. Use clear camelCase names like firstName, uploadCount, and totalAmount.

Is this name allowed?
  • userName
  • 2fast
  • $price
  • _count
  • my-name
  • class
  • café
  • firstName2
  • total amount
Try it yourself
0 of 9 correct

Put each name in a group: allowed or not allowed. If you pick the wrong group, you'll see which rule the name breaks.

Choose a category for every card. You can change an answer at any time; Reset clears them all.
Some words are already taken

Words like let, const, var, class, return, function, and if already have a job in JavaScript. They are called reserved words, and you can't use them as names. Pick a name that says more instead, like lessonClass instead of class.

Why new code doesn't use var

COMPARE

var is part of JavaScript, and older code uses it a lot. It can store values just fine. The problem is its rules. A block is the code between a pair of curly braces { }, like the body of an if. let and const stay inside their block. var doesn't, so its rules don't match the braces you see.

Real-life analogyvar is an old sticky note

A modern label stays in the drawer section where you put it. An old sticky note can slide past the divider into the next section. It can show up before you write on it. And you can stick a second note with the same name over the first one.

In real life: A sticky note that slides past the drawer divider
In JavaScript: var doesn't stay inside its block
In real life: A blank note that is there before you write on it
In JavaScript: var exists as undefined before its line runs
In real life: A second note stuck over the first one
In JavaScript: var lets you declare the same name twice

The table compares the three keywords. Each row asks one question. Each column gives the answer for one keyword.

How const, let, and var are different
What you want to knowconstletvar
Should you use it in new code?Yes. Use it first, for names that never get a new value.Yes, for names that need a new value later.No. Leave it in old code.
Can the name get a new value?No. It throws a TypeError.Yes.Yes.
Can the inside of its array or object change?Yes.Yes.Yes.
Where can you use the name?Only inside its block { }.Only inside its block { }.In the whole function or script, even outside the block.
Can you declare the same name twice in one place?No. It's a SyntaxError.No. It's a SyntaxError.Yes.
What if you read it before its line runs?It throws a ReferenceError.It throws a ReferenceError.You get undefined.
In a classic script, does a top-level one become part of window?No.No.Yes.

Here are the traps one by one. Each var example comes with a matching let example, and each shows the real result.

var inside a block leaks outPop out in the code editor (opens in a new tab)JavaScript
if (true) {  var mood = "visible outside";}console.log(mood);
let inside a block stays insidePop out in the code editor (opens in a new tab)JavaScript
if (true) {  let mood = "hidden outside";}console.log(mood);
Reading var before its line runsPop out in the code editor (opens in a new tab)JavaScript
console.log(score);var score = 5;
Reading let before its line runsPop out in the code editor (opens in a new tab)JavaScript
console.log(score);let score = 5;
Declaring var twicePop out in the code editor (opens in a new tab)JavaScript
var count = 1;var count = 2;console.log(count);
Declaring let twicePop out in the code editor (opens in a new tab)JavaScript
let count = 1;let count = 2;console.log(count);
  • A var made inside an if block can still be used after the block ends. The let version throws a ReferenceError after the block. A ReferenceError means JavaScript can't find that name.
  • Reading a var before its line runs prints undefined. That's because JavaScript makes every var name early, before the code runs, and gives it undefined. This is called hoisting. Reading a let before its line runs throws a ReferenceError instead. The time before the line runs is called the temporal dead zone.
  • var lets you declare the same name twice in one place. let and const don't. They throw a SyntaxError, which means the code is written in a way JavaScript doesn't accept.
Changing old code from var

Don't swap every var for const without checking. First, look for names that get a new value later, and use let for those. Then run the code or its tests to check that it still works. A later lesson on scope covers the few old patterns that need more care.

A top-level var becomes part of windowPop out in the code editor (opens in a new tab)JavaScript
var oldGlobal = "window property";let modernGlobal = "not a window property";console.log(window.oldGlobal);console.log(window.modernGlobal);

A classic script is a plain <script> tag on a web page. window is the object that stands for the browser page. In a classic script, a var at the top level, outside every function and block, also becomes a property of window. So line 3 prints window property. A top-level let or const doesn't do this, so line 4 prints undefined. Modules, a newer kind of script file, have their own rules. Either way, the advice is the same: don't write var in new code.

Scope means the part of your code where a name can be used. Scope, hoisting, and the temporal dead zone each get a full lesson in Stage 4. The Closures lesson shows why old loops written with var caused famous bugs.

Where you will use variables

TRY IT

Real apps use variables to keep track of things. Variables give names to the parts that change or matter, like:

  • counters, like the number of photos uploaded
  • settings, like a light or dark theme
  • messages to show the user
  • the item a user picked
  • results you work out on the way, which make long code easier to read

Further down, a playground lets you change the number of tea packs in a cart. In it, price stays the same, so it is a const. total gets a new value after the multiplication, so it is a let. A running total in a checkout, or a counter on a page, works the same way.

A number typed into a form arrives as textPop out in the code editor (opens in a new tab)JavaScript
const quantityText = "2";
const price = 3;
console.log(typeof quantityText);
const total = Number(quantityText) * price;
console.log(total);

A form field is a box on a web page where the user types, like a quantity box. The browser gives you what was typed as text, even in a box made for numbers. Line 1 stands in for that: the quantity is the text "2". Line 3 uses typeof, which tells you what kind of value something is. It prints string, JavaScript's word for text. Line 4 uses Number(quantityText) to turn the text into the number 2, then multiplies it by the price. Line 5 prints 6. The Numbers lesson explains this kind of change in more detail.

Cart total playground
Calculate a cart totalPop out in the code editor (opens in a new tab)JavaScript
const price = 3;const quantity = 2;let total = price;total = total * quantity;console.log(total);
Live valuesCart
price3
quantity2
total6
Try it yourself

price stays 3 because it is a const. total starts as the price. Then line 4 gives total a new value, 6. That is why total is a let.

Change the number and watch the code and the values update. Reset goes back to two tea packs.
const and let together in a small appPop out in the code editor (opens in a new tab)JavaScript
const appName = "PhotoBox";let uploadCount = 0; uploadCount = uploadCount + 1; const settings = { theme: "dark" };settings.theme = "light"; console.log(appName, uploadCount, settings.theme);

appName never changes, so it is a const. uploadCount goes up each time the user uploads a photo, so it is a let. settings stays the same object the whole time, so it can be a const, even though the theme inside it changes.

A good habit

When you check your own code, every let needs a reason. If a name never gets a new value, make it a const.

Common mix-ups

“const means the value can never change.”

Not quite. const only means the name can't get a new value. If the value is an object or an array, what is inside it can still change.

“= checks whether two values are equal.”

No. = puts a value into a variable. To check whether two values are equal, you use other signs. The course covers them later.

“var is just an older spelling for let.”

No. var has different rules. It doesn't stay inside blocks, only inside functions. It exists as undefined before its line runs. It lets you declare the same name twice. And in a classic script, a top-level var becomes a property of window.

“A name that is allowed is always a good name.”

Not always. $x and café are allowed. But a good name also tells other people what the value is for.

“Two variables always mean two separate values.”

Not always. Two variables can lead to the same object or array. A change made through one name shows up through the other name too.

Practice exercises

5 EXERCISES

Try each task before you open the hints. The answer check doesn't mind capital letters or extra spaces. JavaScript itself is stricter, so the code has to be exactly right.

Exercise 1 · Warm-upGuess the two printed values

What two values does this program print?

Starter codePop out in the code editor (opens in a new tab)JavaScript
let coins = 1;
coins = coins + 4;
const wallet = ["card"];
wallet.push("receipt");
console.log(coins);
console.log(wallet.length);

Answer, then press Check. Spacing and letter case don’t matter.

    Exercise 2 · PracticeFix a const that needs a new value

    This program throws an error. Change one word to fix it. Which word do you use?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    const total = 0;
    total = total + 5;
    console.log(total);

    Answer, then press Check. Spacing and letter case don’t matter.

      Exercise 3 · PracticeChoose let or const

      A photo app has three variables. appName is the app's name and never changes. uploadCount goes up by 1 after each upload. settings is an object, and the theme inside it changes from dark to light. Pick a keyword for each one. Type the three keywords in order.

      Answer, then press Check. Spacing and letter case don’t matter.

        Exercise 4 · PracticeFix names that aren't allowed

        Fix these names so JavaScript allows them, but keep what they mean: 2fast, total amount, and class.

        Answer, then press Check. Spacing and letter case don’t matter.

          Exercise 5 · ChallengeFind the var bug

          Guess what the buggy program prints. Then look at the fixed version, where the value inside the block stays inside the block.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          if (true) {
            var status = "draft";
          }
          console.log(status);

          Answer, then press Check. Spacing and letter case don’t matter.

            Quiz: check your understanding

            8 QUESTIONS

            Your first try counts. Every answer explains why it is right or wrong. For code questions, go through the code line by line before you choose.

            Lesson quiz · 8 questionsScore: first tries count
            1. Question 1 of 8Which keyword should you use first, for a variable that will never get a new value?

              Choose an answer to see the explanation.

            2. Question 2 of 8What does this program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              let score = 0;
              score = 10;
              score = score + 5;
              console.log(score);

              Choose an answer to see the explanation.

            3. Question 3 of 8Which line is mutation (a change inside the array) rather than reassignment (a new value for the name)?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const cart = ["pen"];
              cart.push("book");

              Choose an answer to see the explanation.

            4. Question 4 of 8What happens here?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              const total = 0;
              total = 1;

              Choose an answer to see the explanation.

            5. Question 5 of 8Which variable name is not allowed?

              Choose an answer to see the explanation.

            6. Question 6 of 8What does this var program print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(score);
              var score = 5;

              Choose an answer to see the explanation.

            7. Question 7 of 8Why doesn't new JavaScript code use var?

              Choose an answer to see the explanation.

            8. Question 8 of 8Which rule is best?

              Choose an answer to see the explanation.

            Key takeaways

            • A variable is a name for a value.
            • const stops the name from getting a new value. It does not lock what is inside an object or array.
            • Use let for names that need a new value later, like counters and running totals.
            • Names can use letters, $, _, and digits after the first character. They can't have spaces or hyphens, start with a digit, or be a reserved word.
            • Don't use var in new code. It leaks out of blocks, exists before its line runs, allows the same name twice, and can add to window.

            Remember the one-liner.
            A variable is a name for a value. Use const first, use let when the name needs a new value, and leave var in old code.

            Up next: Data types. You'll meet the kinds of values a variable can hold.

            CompleteFrontend Clear concepts. Working examples.