What you'll be able to do

By the end of this page you should be able to give a value a name, change that name when you mean to, and leave it alone when you do not. You will also recognize var when an old tutorial or a copied snippet uses it, without treating it as the default for new code.

A variable is not a mysterious box in the computer. It is a name you choose so you can use a value again — a city, a score, a button you already found on the page.

Previous post: statements, comments, and reading errors.

Who this is for

  • People who have typed const city = "Pune" and are not sure why the next tutorial uses let instead
  • Beginners who saw var in a 2014 Stack Overflow answer and thought that is still the main way
  • Anyone who got a TypeError after writing const count = 0; and then count = 1;

You can skip this if you already default to const, switch to let only when the name must be reassigned, and you know var is leftover function-scoped syntax. Come back when a snippet full of var still feels like a different language.

A name for a value

When you write:

const city = "Jaipur";
console.log(city);

you are not “creating JavaScript.” You are sticking a label on a piece of data. Later lines can say city instead of typing "Jaipur" again. If the value needs to change — a score that goes up, a message that updates after a click — you still use a name; you just pick a keyword that allows that change.

Scenario A — a value that should stay the same. A tax rate, a page title string you set once, or the button you looked up with getElementById. You do not want a later line to accidentally point that name at something else.

Scenario B — a value that is supposed to change. A click counter, a step in a loop, or “the current city the user picked.” The name stays; the value behind it moves.

The rule: decide whether the name should be allowed to point at a new value. That decision is const versus let. It is not “is this data holy forever.”

const — the default for new code

const means: this name cannot be pointed at a different value later. The first assignment is the only assignment for that name.

const city = "Pune";
console.log(city);

Scenario A — this is what you want. You found a button once and you will keep using that same button:

const button = document.getElementById("go");
button.addEventListener("click", function () {
  console.log("clicked");
});

You are not going to say button = somethingElse later. const makes that accident a loud error instead of a quiet bug.

Scenario B — the beginner surprise: const does not freeze objects.

const user = { name: "Raman" };
user.name = "Asha";
console.log(user.name);

This prints Asha. const stopped you from writing user = { name: "Asha" } (a whole new object on that name). It did not lock the insides of the object. We will go much deeper on this when we reach objects and references. For today: const protects the binding (the arrow from the name to the value), not every nested field.

If you try to reassign a const name:

const count = 0;
count = 1;

you get a TypeError. That is the engine saying “you promised this name would not move.” Use let if the name must move.

let — when the name must be updated

let means: this name can be pointed at a new value later.

let score = 0;
score = score + 1;
console.log(score);

Scenario A — a counter on a page. Each click adds one. The name score stays; the number changes. That is let.

Scenario B — swapping a message.

let message = "Nothing yet";
message = "Button was clicked";
console.log(message);

Same name, new text. If you had used const, the second line would throw.

You cannot declare the same let name twice in the same block:

let city = "Pune";
let city = "Jaipur";

That is a SyntaxError (the name is already taken in this block). Update with city = "Jaipur" if you used let, or use a new name if these are two different ideas.

A simple habit that saves pain: start with const. When the engine complains that you need to assign again, switch that one name to let. Do not start every line with let “just in case.”

var — why it still appears

var is the old way to declare a name. It still works. You will see it in old tutorials, copied answers, and some generated code. New code in this series uses let and const.

The important difference for a beginner is scope, which here means “where the name is visible.”

Scenario A — let inside a block stays inside that block.

if (true) {
  let inside = "only in here";
  console.log(inside);
}
// console.log(inside); // ReferenceError if you uncomment this

The name inside belongs to the { } block. Outside, it does not exist. That is usually what you wanted.

Scenario B — var leaks out of that same block.

if (true) {
  var leaked = "I escape the if";
}
console.log(leaked);

This prints the string. var is function-scoped (or global if you are not inside a function), not block-scoped. Beginners then get names colliding in surprising places, especially inside loops — a classic “why did every button remember the last index?” bug. We will unpack loops and closures later. For now: do not use var in new files.

If you must read old code, translate in your head: var is a looser let that ignores block braces. Prefer rewriting it to let or const when you own the file.

You also should not redeclare with let/const, but var allows this:

var n = 1;
var n = 2;
console.log(n);

That silent second declaration is a footgun. Two let n lines in the same block refuse to compile, which is the kinder behavior.

A tiny page to feel the difference

Save as names.html, open it, click the button, and watch the paragraph and the console.

<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8" />
    <title>let and const</title>
  </head>
  <body>
    <p id="out">Clicks: 0</p>
    <button id="go">Add one</button>
    <script>
      const out = document.getElementById("out");
      const button = document.getElementById("go");
      let clicks = 0;

      button.addEventListener("click", function () {
        clicks = clicks + 1;
        out.textContent = "Clicks: " + clicks;
      });
    </script>
  </body>
</html>

out and button are const because those names should keep pointing at the same elements. clicks is let because the number changes. If you change let clicks to const clicks, the first click should throw when the script tries clicks = clicks + 1.

Mistakes I see a lot

1. Thinking const means the object can never change. const user = { name: "Raman" }; user.name = "Asha"; is allowed. Replacing the whole user is not. If that still feels slippery, you are not behind — objects get their own posts later.

2. Declaring with var because a random blog used it. Copy the idea, not the keyword, unless you are maintaining old code on purpose.

3. Using let for everything, then wondering why a name got overwritten. If a name should only be set once, const turns the overwrite into an error you can see.

4. Redeclaring instead of assigning. let score = 0; then later let score = 1; in the same block is an error. The second time you want score = 1;.

What to try before the next post

  1. In the console, create const city = "Pune" and then try city = "Mumbai". Read the TypeError.
  2. Change that example to let city and assign again. Confirm it works.
  3. Paste the var leaked example and the let inside example. See which name exists after the if.
  4. Build the click counter file. Switch clicks to const on purpose, click once, read the error, then switch it back.

Next in this series: naming, semicolons, and clean basics — readable names, what semicolons actually do in daily code, and habits that make your files look like a person wrote them.

Try this next outside the series

Once the absolute basics feel clear, leave the series for one practical browser step and one simple tool you can use right now.