Skip to content

Variables and values

docs.scrimba.com

Say you are building a checkout page and the price of an item shows up in three places: the product line, the running total, and the confirmation. Type 19.99 into all three by hand and a sale becomes an afternoon of find-and-replace. Store it once under a name and change it in one place, and every spot that uses it updates with you. That name is a variable, and this chapter is about how to make one, when to lock it, and what to call it.

Storing a value

A variable is a name you give to a value so you can use it again later. You create one with the word let, then a name, then =, then the value you want to store:

js
let userName = "Sam";
console.log(userName); // Sam

That line says: take the text "Sam" and remember it under the name userName. From then on, wherever you write userName, JavaScript hands back what you stored.

Read the = as "put this value under this name". It is not the equals sign from maths class, where both sides are already the same. It is an instruction: take the value on the right, and stash it under the name on the left.

Because it is a store-this instruction, you can change your mind later. Write the name and = again with a new value, and JavaScript keeps the newest one:

js
let score = 0;
score = 10;
console.log(score); // 10

The first line makes score and puts 0 in it. The second gives it a new value. There is no second let, because score already exists; you are updating it, not making it again.

A variable is a name bound to a value. You declare it with let and set its value with the assignment operator =:

js
let total = 0;
total = 42;
console.log(total); // 42

The = is assignment, not comparison. It evaluates the expression on the right, then stores the result under the name on the left. This is why = means "assign this value", never "is equal to"; the comparison you will meet in operators is a separate symbol, ===.

Declaring with let creates the name; assigning to it again updates the value it holds. You only use let once per variable. After that, the bare name on the left is enough:

js
let itemPrice = 19.99;
itemPrice = 24.99;
console.log(itemPrice); // 24.99

The value on the right can be any of the data types JavaScript has: text, a number, a boolean. The variable does not care which; it holds whatever you last assigned.

A variable is an identifier (a name in your code) bound to a value. The = is the assignment operator: it evaluates the right-hand expression and binds the result to the name on the left. It never tests equality, and it never copies a value into a fixed box; it points a name at a value.

js
let total = 0;
total = 42;
console.log(total); // 42

Reassignment does not create a new variable, it repoints the existing binding. That distinction stays invisible with primitives like numbers and strings, where each value is separate and self-contained. It starts to matter the moment a variable holds something shared, like an object, because then two names can point at the same value and a change through one shows up through the other. You will see that in full when objects arrive; for now, hold the idea that a name points at a value rather than containing it.

One more thing the = does not do: it does not lock the value in place. let score = 0 says "point score at 0 for now", and the next line is free to point it somewhere else. Whether a binding can be repointed at all is the difference between let and const, which is next.

JunoStoring a value A variable is a name for a value you want to reuse, and you make one with let name = value. Read the = as "put this value under this name", not as maths-class equals. To change it later, write the name and = again with no second let, and JavaScript keeps the newest value.
JunoStoring a value Declaring with let creates a name; assigning with = stores a value under it. The = is assignment, not comparison, so it never means "is equal to". You only write let once per variable; after that the bare name updates the value it holds.
JunoStoring a value The = binds a name to a value, it never copies into a box or tests equality. Reassigning repoints the existing binding rather than making a new variable. That stays invisible with numbers and strings and starts to bite once a name points at something shared, so keep "the name points at the value" in mind before objects show up.

let vs const

There are two words for making a variable: let and const. You have seen let. Use const when the value should never change after you set it:

js
const taxRate = 0.2;
console.log(taxRate); // 0.2

A tax rate is fixed, so const fits: it says "this is set, and I do not want it changing by accident". If you try to reassign a const, JavaScript stops you with an error, which is a helpful guardrail.

Reach for const first. Use let only when you know the value will change, like a score that goes up or a total you add to. If a value stays the same for its whole life, const says so and protects it.

js
const currency = "USD";
let itemsInCart = 0;
itemsInCart = 3;
console.log(itemsInCart); // 3

The currency will not change, so it is const. The cart count will, so it is let.

JavaScript gives you two ways to declare a variable, and the choice is about whether the value will be reassigned. const declares a constant binding: once you assign it, you cannot point that name at a new value.

js
const taxRate = 0.2;
taxRate = 0.25; // TypeError: Assignment to constant variable.

let allows reassignment; const forbids it. The rule that keeps code clean is to reach for const by default, and use let only when you must reassign. Most variables are set once and read many times, so most of them should be const.

js
const currency = "USD";
let runningTotal = 0;
runningTotal = 19.99;
console.log(runningTotal); // 19.99

const is not about the value being special; it is a signal to anyone reading the code, including you next week, that this name will not move. That signal makes a program easier to follow, because a const you can trust to stay put.

Both let and const declare a binding (the link between a name and a value). The difference is whether that binding can be reassigned. const freezes the binding: after the initial assignment, pointing the name at a new value is a TypeError.

js
const taxRate = 0.2;
taxRate = 0.25; // TypeError: Assignment to constant variable.

Default to const and drop to let only where reassignment is real. This is not stylistic fussiness; a const is a fact you can rely on while reading, one fewer name that might change under you, and that narrows where a bug can live.

The subtlety worth stating early: const fixes the binding, not the contents. It stops you repointing the name, but if the value is something with internal parts, those parts can still change. A number or a string has no internal parts to change, so with those const behaves exactly like "this value is fixed". With an object, though, const only guarantees the name keeps pointing at the same object; the object's own contents remain editable. That gap surprises people, and it is easier to absorb now than mid-debug, so objects return to it directly.

js
const currency = "USD";
let runningTotal = 0;
runningTotal = 19.99;
console.log(runningTotal); // 19.99

There is a third, older keyword you will meet in existing code: var. Do not use it. It differs from let in two ways that cause bugs. First, var is function-scoped: it ignores the { } blocks that let and const respect, so a var declared inside a block leaks out to the whole surrounding function, while let and const are block-scoped and stay inside the nearest { }. Second, var is hoisted: the declaration is treated as if it moved to the top of its scope, so a var name exists (holding undefined) before the line that declares it, which hides mistakes rather than catching them.

let and const are hoisted too, but reaching them before their declaration line throws instead of silently giving undefined; that early window is called the temporal dead zone, and the error it produces is a feature, since it turns a silent bug into a loud one. The short version: write const by default, let when you must reassign, and treat var as read-only knowledge for maintaining old code.

Junolet vs const Use const for a value that should never change, and let for one that will. Reach for const first, and switch to let only when you know the value needs to change. Reassigning a const gives you an error, which is the guardrail doing its job.
Junolet vs constconst forbids reassignment; let allows it. Default to const and reach for let only when a value has to change. A const tells the next reader this name will not move, and most variables are set once and read many times, so most of them should be const.
Junolet vs constconst freezes the binding, not the contents, so reassigning the name is a TypeError but an object it points at can still be edited. Default to const, use let only for real reassignment, and treat the old var as read-only knowledge, since it is function-scoped and hoisted in ways that hide bugs. The binding-versus-contents gap catches people, so keep it in mind for when objects arrive.

Naming variables

A variable name has a few rules. It can use letters, digits, _, and $, but it cannot start with a digit, and it cannot contain spaces:

js
let firstName = "Sam";
let item2 = "book";

Names are case-sensitive, which means firstName and firstname are two different variables. Getting the capitals wrong is a common early mistake, so it helps to keep names consistent.

The style JavaScript developers use is called camelCase: start lowercase, and capitalise the first letter of each later word, with no spaces. So firstName, itemPrice, isLoggedIn.

js
let itemPrice = 19.99;
let isLoggedIn = true;

Beyond the rules, aim for names that say what they hold. price beats p, and userName beats x. You will read your code far more than you write it, and clear names are what make it readable.

The rules for a valid name: it may contain letters, digits, _, and $, may not begin with a digit, and may not include spaces or reserved words like let. Names are case-sensitive, so total and Total are separate variables.

Within those rules, the convention is camelCase: lowercase first word, each following word capitalised, no separators.

js
let firstName = "Sam";
let itemPrice = 19.99;
let isLoggedIn = true;

Convention is not enforced by the language, but it is enforced by every codebase you will work in, so follow it from the start. A boolean often reads well with an is or has prefix (isLoggedIn, hasDiscount), which signals at a glance that the value is true or false.

The name is documentation. daysUntilExpiry tells the next reader what the value means; d makes them go hunting. Descriptive names cost a few keystrokes and save real time, so spend them.

The lexical rules: a valid identifier (a name in code) may contain letters, digits, _, and $, may not start with a digit, and may not be a reserved word (let, const, return, and the like). Identifiers are case-sensitive, so total and Total are distinct.

The convention layered on top is camelCase for variables, and it is worth treating as non-negotiable even though the language does not enforce it. Tooling, teammates, and every popular style guide assume it, so deviating adds friction for no gain.

js
const firstName = "Sam";
const itemPrice = 19.99;
const isLoggedIn = true;

The higher-value habit is naming for meaning. A name is the cheapest documentation you have and the one most likely to stay accurate, because it sits on the value it describes. remainingCredits survives a refactor that a comment saying "credits left" might not. Booleans read best as a yes/no question (isActive, hasAccess), and avoid names that lie after a change, like a const total you keep adding conceptually to; if the meaning drifts, rename it. Clear naming is the highest-leverage habit in this chapter, and it is free.

JunoNaming variables A name can use letters, digits, _, and $, but cannot start with a digit or contain spaces. Names are case-sensitive, so firstName and firstname are different. Use camelCase like itemPrice, and pick names that say what they hold, so price over p.
JunoNaming variables Valid names use letters, digits, _, and $, never start with a digit, and are case-sensitive. The convention is camelCase, and although the language does not enforce it, every codebase does, so follow it from day one. A descriptive name is documentation that stays accurate, so spend the keystrokes on daysUntilExpiry over d.
JunoNaming variables Identifiers allow letters, digits, _, and $, cannot start with a digit, cannot be reserved words, and are case-sensitive. Use camelCase; the language does not enforce it but every tool and teammate assumes it. Naming for meaning is the highest-leverage habit here, and it costs nothing, so make remainingCredits the default over r.

Where variables go from here

Variables are the foundation everything else sits on: a value is not useful until it has a name you can reach it by. You now have the three moves that matter, storing a value with let, locking one with const, and naming it well, and you will use all three in every program you write from here.

Next you will look at the values themselves in data types: the text, numbers, and booleans you have been storing, and what makes each one behave the way it does. After that, operators show you how to combine those values, and functions let you name a piece of work the way a variable names a value.