Variables and Data Types
In this lesson, you'll learn how to store information in variables and work with different types of data. Variables are like labeled boxes where you can store values and use them later in your code.
What You'll Learn
By the end of this lesson you will finish a small program that inspects three fixed values and reports on them: naming a value's type with typeof, assembling a labelled sentence out of a name and a number, and turning a comparison into a stored true/false. It reports its own pass or fail, so you will know when you are done.
You arrive able to print a value and read the result (01-introduction); you leave able to hold values in named variables, and to say what kind of value each one is.
This lesson is not marked required for the final project, but it is load-bearing in practice: every later lesson stores something in a const or a let, and the Task Manager in 15-capstone-project is a pile of exactly these — a title that is a string, a status that is a string, a completion flag that is a boolean, an id that must be a number and not text.
Declaring Variables
JavaScript has three ways to declare variables:
// let - for variables that can change
let age = 25;
console.log("Age:", age);
age = 26; // We can change it
console.log("New age:", age);
// const - for variables that won't change
const birthYear = 1998;
console.log("Birth year:", birthYear);
// birthYear = 1999; // This would cause an error!
// var - old way (avoid using this)
var name = "Alice";
console.log("Name:", name);
Best Practice: Use const by default. Only use let when you know the variable will change. Avoid var.
Basic Data Types
JavaScript has several built-in data types. Let's explore the most common ones:
Strings
Strings are used for text. You can use single quotes, double quotes, or backticks:
// Different ways to create strings
let greeting = "Hello";
let name = 'JavaScript';
let message = `Welcome to ${name}!`; // Template literal
console.log(greeting);
console.log(name);
console.log(message);
// String concatenation
let fullGreeting = greeting + ", " + name + "!";
console.log(fullGreeting);
Numbers
JavaScript has one number type for both integers and decimals:
// Integers
let count = 42;
console.log("Count:", count);
// Decimals (floating-point)
let price = 19.99;
console.log("Price:", price);
// Mathematical operations
let sum = 10 + 5;
let difference = 10 - 5;
let product = 10 * 5;
let quotient = 10 / 5;
let remainder = 10 % 3;
console.log("Sum:", sum);
console.log("Difference:", difference);
console.log("Product:", product);
console.log("Quotient:", quotient);
console.log("Remainder:", remainder);
Booleans
Booleans represent true or false values:
let isLearning = true;
let isComplete = false;
console.log("Is learning:", isLearning);
console.log("Is complete:", isComplete);
// Comparison operations return booleans
console.log("5 > 3:", 5 > 3);
console.log("5 < 3:", 5 < 3);
console.log("5 === 5:", 5 === 5);
console.log("5 !== 3:", 5 !== 3);
Undefined and Null
Two special values for "nothing":
// undefined - variable declared but not assigned
let notDefined;
console.log("Not defined:", notDefined);
// null - intentionally empty
let empty = null;
console.log("Empty:", empty);
Type Checking
You can check the type of a value using typeof:
typeof exists because JavaScript variables do not declare a type — a let can hold a string on one line and a number on the next. When you need to know what you actually have, you ask:
// typeof always answers with a STRING naming the type, never the type itself.
// That is why the results below are quoted: "number" is text, not a number.
console.log(typeof "Hello");
console.log(typeof 42);
console.log(typeof true);
console.log(typeof undefined);
// And one famous exception, worth memorising now: null reports as "object".
// It is a bug from 1995 that could never be fixed without breaking the web,
// so the reliable test for null is value === null, not typeof.
console.log(typeof null);
Now finish one yourself before the build task asks for it under check. Copy this into the Run box and replace each ___:
const entered = "42";
// 1. Convert entered to a real number, using the function shown above.
const asNumber = ___;
console.log("Entered:", entered, "type:", typeof entered);
console.log("As number:", asNumber, "type:", typeof asNumber);
console.log("Plus one:", asNumber + 1);
// 2. Predict this last line BEFORE running: entered was never converted.
console.log("Without converting:", entered + 1);
With Number(entered) in the blank it prints As number: 42 type: number and Plus one: 43. The last line prints Without converting: 421 — + joined the text "42" and 1 instead of adding them, which is the trap the block below is about.
Recall
Reaching back to 01-introduction, no scrolling: how do you write a comment that spans several lines in JavaScript?
Type Conversion
JavaScript can convert between types:
// String to Number
let strNumber = "42";
let num = Number(strNumber);
console.log("String to number:", num);
console.log("Type:", typeof num);
// Number to String
let number = 42;
let str = String(number);
console.log("Number to string:", str);
console.log("Type:", typeof str);
// Automatic conversion (coercion): each of these mixes a string with a number.
// Predict all three before you run them — the three operators do NOT agree.
console.log("5" + 3);
console.log("5" - 3);
console.log("5" * "2");
Run it. If any of the three surprised you, that is the point of the block below — commit to an answer before scrolling further.
Predict
Same two numbers, two different operators. Trace both lines by hand before running. What does this log?
let a = "10" + 5;
let b = "10" - 5;
console.log(a);
console.log(b);Ordering a Conversion
Conversion has a natural order, and const enforces it. Reassemble this one.
Arrange the code
Reassemble the body of priceLabel(), which takes a price that arrived as text and prints it rounded to whole dollars. Every line uses a name the line above it introduces. Find the only arrangement that runs — and then answer the real question: why must they run in this order and no other?
const rounded = Math.round(amount);const amount = Number(raw);const raw = "19.99";console.log("About " + rounded + " dollars");
Why that order? Each line needs the value the line above produced. And because these are const declarations, reading one too early is not a silent wrong answer — it is a ReferenceError that stops the program.
When the Type Is Not What You Think
Here is the typeof null quirk, no longer a footnote. This program runs cleanly, exits 0, and gives the wrong answer.
Debug
This should report how many of the four values are empty — null counts as empty, a real value does not. There are two nulls in the list, so it should print 2. It runs without any error and prints something else. Form a hypothesis about WHY before you change anything: what is isEmpty actually testing?
// Report whether each value is "empty" — null counts as empty, a real value does not.
const values = [null, "Alice", null, 42];
function isEmpty(value) {
return typeof value === "null";
}
let emptyCount = 0;
for (const value of values) {
if (isEmpty(value)) {
emptyCount = emptyCount + 1;
}
}
console.log("Values checked:", values.length);
console.log("Empty values found:", emptyCount);Expected output:
Values checked: 4 Empty values found: 2
Try It Yourself
Reading about types is not the same as working with them. This is a build task: a small program that reports its own pass/fail. You are given three fixed values and three unfinished const declarations, each one leaning on something this lesson taught — typeof, template literals, and a comparison that returns a boolean. Run it as-is and it fails immediately, telling you which value is still wrong. Fill each declaration in until every check passes and it prints All checks passed.
Nothing above spells out all three answers in one place — you've seen typeof, template literals, and comparison operators as separate ideas, so you'll assemble them yourself. The starter already has the data, the placeholders, and the checks; you replace only the right-hand side of each const.
Build
Finish the build. Three const declarations start out as undefined placeholders, and the checks below them fail until each one holds the right value. Run it as-is to see which check fails first, decide what that value should be, then replace each placeholder until it prints 'All checks passed.' The checks run top to bottom, so the first failure you see is TODO 1 — fix it first, then work down.
const assert = require('assert');
// The data: a small set of values to inspect. Do NOT change these.
const sampleNull = null;
const personName = "Alice";
const personAge = 20;
// TODO 1: the type of sampleNull as a string, using typeof.
// typeof null -> "object"
const nullType = undefined; // replace undefined with your code
// TODO 2: a one-line label from personName and personAge, using a template literal.
// "Alice" and 20 -> "Alice is 20 years old"
const label = undefined; // replace undefined with your code
// TODO 3: whether personAge is 18 or older, as a boolean.
// 20 >= 18 -> true
const adult = undefined; // replace undefined with your code
// --- Build checks: these must all pass. Do not edit below this line. ---
assert.strictEqual(
nullType,
"object",
"nullType should be the type of sampleNull as reported by typeof",
);
assert.strictEqual(
label,
"Alice is 20 years old",
"label should combine personName and personAge into one labeled string",
);
assert.strictEqual(
adult,
true,
"adult should be a boolean for whether personAge is 18 or older",
);
console.log("All checks passed.");
console.log("Type of null:", nullType);
console.log("Label:", label);
console.log("Is adult:", adult);Expected output:
All checks passed. Type of null: object Label: Alice is 20 years old Is adult: true
Once it passes, try two variations and predict each before running:
- The
typeof nullquirk, turned around. ChangenullTypetotypeof personNameinstead oftypeof sampleNull. Before you run it, decide whattypeofreports for a string and which check breaks — the first assert wants"object", the value this lesson's quirk gives fornull, so a"string"there is an instructive failure that proves you know which value produces"object". - Loose value, strict check. Change
adulttopersonAge === "20"— comparing the number20to the string"20"with strict equality. Predict whetheradultcomes outtrueorfalsebefore running, then check:===compares type as well as value, so a number and a string are never strictly equal, and the boolean check fails.
Taking It Somewhere New
Transfer
In JavaScript a variable has no declared type: it holds whatever you put in it, and typeof tells you at RUN TIME what that turned out to be. New setting: TypeScript, a language that is JavaScript plus type annotations, where you write let count: number = 0 and the type is checked before the program ever runs. What is the same about the two, and what genuinely changed?
// JavaScript — the type is discovered while running.
let count = 0;
count = "three";
console.log(typeof count);
// TypeScript — the same two lines, with the type written down.
// let count: number = 0;
// count = "three";Key Takeaways
- Use
constfor values that don't change,letfor values that do - JavaScript has several data types: strings, numbers, booleans, undefined, and null
- Strings can be created with quotes or backticks (template literals)
- Use
typeofto check a value's type - JavaScript can automatically convert between types (type coercion)
Next Steps
Now that you understand variables and data types, you're ready to learn about functions - reusable blocks of code that make your programs more organized and powerful!
Pro Tip: Try printing different types of values and see how they behave. Experiment with mathematical operations and string concatenation to get comfortable with how JavaScript handles different data types.
Next lesson
Functions in JavaScript
Learn how to create reusable code with functions
18 min