completefrontend
Open lab My progress
THE JAVASCRIPT FIELD GUIDE

Data types

Meet JavaScript's seven primitive types and objects, learn what typeof really reports, and see why variables can hold different kinds of values over time.

By the end, you can
  • 01
    Tell primitives from objectsSay whether copying a value makes a separate copy, or makes two variables point to the same object.
  • 02
    Name all eight JavaScript typesKnow string, number, bigint, boolean, undefined, symbol, null, and object when you see them.
  • 03
    Use typeof wellRead what typeof really gives back, including its surprises for null, arrays, functions, and NaN.

Values have types

Every value in JavaScript has a type. The type says what kind of value it is. For example, "Asha" is text, and 3 is a number.

The type also decides what you can do with the value. You can add two numbers. You can turn text into capital letters. The type belongs to the value, not to the variable. A variable is only a name that holds a value.

The short definition

JavaScript has eight types. Seven of them are primitive types: one simple value, like 5 or "hi". The eighth type is object: a value that can hold other values inside it. You can't change a primitive; you can only replace it. You can change what is inside an object.

Two values, two typesPop out in the code editor (opens in a new tab)JavaScript
const user = "Asha";
const unreadCount = 3;
console.log(typeof user);
console.log(typeof unreadCount);

Line 1 stores the text "Asha" in a variable called user. Line 2 stores the number 3 in a variable called unreadCount.

Lines 3 and 4 use typeof. It gives back the name of a value's type, as text. So line 3 prints string and line 4 prints number. "String" is JavaScript's word for text.

In Why JavaScript?, "5" + 3 gave "53". That happened because "5" is a string and 3 is a number. When you put a string and a number together with +, JavaScript joins them as text.

In the Variables: let, const & var lesson, you met two ways to change things:

  • Reassignment: put a new value in a variable, like b = 6.
  • Mutation: change something inside an object, like box.n = 2.

The type of a value decides which of the two can happen. You'll see how in the next section. This lesson is a short tour of all eight types. Each type gets its own lesson later, starting with Numbers & math next.

Primitives vs objects

STEP THROUGH

JavaScript values come in two families:

  • A primitive is one simple value, like 5, "Ada", true, or null. You can't change part of it. To get a different value, you replace it with a new one.
  • An object holds other values inside it, each under a name. Each named value is called a property. In { n: 1 }, the property n holds 1. Code can change properties.

The two families are also copied in different ways:

  • A variable with a primitive holds the value itself. Copying it makes a second, separate value.
  • A variable with an object holds a reference: a pointer that says where the object is. Copying it copies only the pointer. Then both variables point to the same object.
Real-life analogyPrimitives are sticky notes

Think of a as a sticky note with 5 written on it. let b = a makes a second sticky note that also says 5. Writing 6 on the second note doesn't change the first note.

In real life: A sticky note that says 5
In JavaScript: A variable a that holds the number 5
In real life: Copy the note onto a new note
In JavaScript: let b = a copies the number
In real life: Write 6 on the new note
In JavaScript: b = 6 puts a new value in b
In real life: The first note still says 5
In JavaScript: a is still 5
After let b = a and then b = 6. Box a holds a card with 5. Box b holds its own card with 6. a is still 5.let b = a; b = 6;5a6ba is still 5only b changed
let b = a gives b its own copy of 5. Then b = 6 swaps only the card in b. The card in a still says 5.
Real-life analogyObjects are houses; variables hold addresses

An object is like a house. A variable doesn't hold the house. It holds a card with the house's address. Copying the card doesn't build a second house. If someone paints the front door, everyone with that address sees the new color.

In real life: A house
In JavaScript: An object like { n: 1 }
In real life: A card with the house's address
In JavaScript: A variable that points to the object
In real life: Copy the address card
In JavaScript: const box2 = box1 copies the reference
In real life: Paint the front door
In JavaScript: box2.n = 2 changes the object, and box1 sees it too
After const box2 = box1. Two name tags, box1 and box2, both point to the same object. The object holds n: 2.const box2 = box1;box1box2n: 2objectone object
const box2 = box1 copies only the reference, not the object. Both names point to the same object, so a change made through box2 shows up through box1 too.
Copy a number, then copy a reference to an object
Step 0 of 8Ready
Your turn: follow the blue line

Guess both printed values first. Then step through: first a number is copied, then a reference to an object.

Running in
  1. script
Next: line 1
let b = a;b = 6;console.log(a); const box1 = { n: 1 };const box2 = box1;box2.n = 2;console.log(box1.n);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
Change line 8: which number goes into the shared object?

Changing this starts the replay again from line 1.

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.

Press Step to run the code one line at a time. Line 4 prints 5. Changing b didn't change a, because a number is a primitive, so b got its own copy.

Line 9 prints 2. box1 and box2 point to the same object, so the change on line 8 shows up through box1. Pick "Set n to 7", and line 9 prints 7 instead.

The lessons Objects & references and Memory: primitives vs objects go deeper. For now, remember one rule: copying a primitive copies the value. Copying an object variable copies the reference, so both variables point to one object.

Capital letters make a new stringPop out in the code editor (opens in a new tab)JavaScript
const tea = "tea";
const loudTea = tea.toUpperCase();
console.log(tea);
console.log(loudTea);

Line 1 stores the text "tea" in tea. Line 2 calls toUpperCase(), which gives back the same text in capital letters. It doesn't change tea. It makes a new string, "TEA", and line 2 stores it in loudTea.

Line 3 prints tea: the first string didn't change. Line 4 prints TEA.

This is what immutable means: a value that can't be changed. Every primitive is immutable. To get a different primitive, you make a new one and store it.

Most objects can be changed. Code can lock an object so its properties can't change, and some objects in the browser are read-only. But for the objects you make yourself, this rule holds: when two variables point to one object, a change made through one variable shows up through the other.

Check whether a value is a primitivePop out in the code editor (opens in a new tab)JavaScript
function isPrimitive(value) {
  const valueType = typeof value;
  return value === null || (valueType !== "object" && valueType !== "function");
}

console.log(isPrimitive("Asha"));
console.log(isPrimitive(["Asha"]));
console.log(isPrimitive(null));
console.log(isPrimitive(() => {}));

Line 1 starts a function: a named set of steps you can run again and again. This one is called isPrimitive. It answers true or false.

  • Line 2 saves the type name of value in valueType.
  • Line 3 gives back true if the value is null. It also gives back true if the type is not "object" and not "function". Here || means "or", and && means "and".
  • Lines 6 to 9 try four values: text, a list, null, and a function. They print true, false, true, and false.

null needs its own check on line 3, because typeof null gives "object". You'll see why in the next section.

The eight types

TABLE

Here are all eight types. Seven of them are primitive types:

  • string: text, like "hi".
  • number: a number, like 42 or 3.14.
  • bigint: a very large whole number. You write it with an n at the end, like 10n.
  • boolean: yes or no. There are only two values, true and false.
  • undefined: no value yet.
  • symbol: a one-of-a-kind ID, made with Symbol(). No two symbols are equal.
  • null: empty on purpose.

The eighth type is object. Plain objects, arrays (lists of values), dates, functions, and Math are all objects.

Left: seven primitive types, shown as seven value cards: hi, 42, 10n, true, undefined, null, and Symbol(). Right: the one object type, shown as a cart holding a list and an object.7 primitive types"hi"4210ntrueundefinednullSymbol()one simple value each1 object type[1, 2]{ a: 1 }objectarrays, functions, dates…
Seven types are primitives: one simple value on each card. The eighth type, object, is like a cart: it can hold other values inside it. Arrays and functions are objects too.
Real-life analogyEight pantry shelves

A pantry is a food cupboard. Think of the eight types as eight shelves in it. You don't need to know every can on day one. You learn the shelf names, so you know where to look.

In real life: A shelf for flour, a shelf for sugar
In JavaScript: One type, like number or string
In real life: A recipe asks for flour
In JavaScript: Some code needs a certain type, like a number to add
In real life: One shelf holds many bags of flour
In JavaScript: One type holds many values: 1, 2, and 3.5 are all numbers

The table below lists the eight types. Read each row as: "a value like this has this type, and typeof gives back this text."

JavaScript's eight types
TypeExample valueWhat does typeof give?What is it for?
string"hi"stringText. The Strings lesson covers it.
number42numberWhole numbers and decimals, plus the special values NaN and Infinity. The next lesson, Numbers & math, covers it.
bigint10nbigintWhole numbers too big for the number type. The BigInt lesson covers it.
booleantruebooleanYes or no: true or false. The Booleans, null & undefined lesson covers it.
undefinedundefinedundefinedNo value yet. A variable you haven't given a value holds undefined.
symbolSymbol("id")symbolA one-of-a-kind ID. No two symbols are equal.
nullnullobjectEmpty on purpose. typeof says object because of an old mistake in JavaScript.
object{}objectPlain objects, arrays, functions, dates, Math, and more. (typeof says function for functions.)

Three rows need extra care:

  • null is a primitive, but typeof null gives "object". This is an old mistake in JavaScript. It was never fixed, so that old websites keep working.
  • Functions are objects, but typeof gives them their own answer, "function".
  • Arrays are objects too, so typeof gives "object". To check for an array, use Array.isArray. You'll meet it soon.
Two ways to say no valuePop out in the code editor (opens in a new tab)JavaScript
const draftTitle = undefined;
const savedTitle = null;
console.log(draftTitle === undefined);
console.log(savedTitle === null);

JavaScript has two values that mean "nothing here":

  • undefined usually means no value was given yet.
  • null means "empty", and code chose it on purpose.

Line 1 stores undefined in draftTitle: a draft that has no title yet. Line 2 stores null in savedTitle: the title was cleared on purpose. Lines 3 and 4 use ===, which checks whether two values are exactly the same. Both lines print true.

Different apps use these two values in different ways. Follow what your app says each one means. typeof alone won't tell you.

Primitive or object?
  • 42
  • "text"
  • true
  • null
  • undefined
  • 10n
  • Symbol()
  • [1, 2]
  • { a: 1 }
  • function () {}
  • new Date()
  • Math
Try it yourself
0 of 12 correct

Put each value in its family: primitive or object. After you sort a card, read its note.

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

The typeof operator

INTERACTIVE

An operator is a symbol or word that works on values, like +. typeof is an operator that asks for the name of a value's type. It gives back that name as a string, such as "number" or "object".

Try typeof on different values
Ask for the typePop out in the code editor (opens in a new tab)JavaScript
const value = null;console.log(typeof value);console.log(Array.isArray(value));
What JavaScript saysnull
The valuenull
typeof valueobject
Is it a primitive?true
Array.isArray(value)false
Try it yourself

For null, typeof gives "object". null is a primitive, but typeof gives object. This old mistake was never fixed, so that old websites keep working.

Your browser runs the real typeof on the value you pick. Line 1 changes to that value.

Pick a value in the playground. Line 1 of the code changes to that value. The panel shows what real JavaScript says about it.

typeof is good for broad questions, like "is this a string?" It always gives one of these eight answers: "string", "number", "bigint", "boolean", "undefined", "symbol", "function", or "object". Four answers surprise people:

  • typeof null is "object". This is the old mistake from the table. When null matters, check value === null first.
  • typeof [] is "object", because arrays are objects. To check for an array, use Array.isArray(value).
  • typeof function () {} is "function". Functions are objects you can call, and typeof gives them their own answer. This one is useful.
  • typeof NaN is "number". NaN means "Not a Number", but it is a special value of the number type. You get it when a math step fails, like Number("tea").
A broken array checkPop out in the code editor (opens in a new tab)JavaScript
function describe(value) {
  if (typeof value === "array") {
    return "array";
  }
  return typeof value;
}

console.log(describe([1, 2]));

This function should give back "array" for an array. Line 2 compares typeof value with "array". But typeof never gives "array", so line 2 is never true. Line 5 runs instead, and the program prints object. The fix is to use Array.isArray on line 2:

The fixed array checkPop out in the code editor (opens in a new tab)JavaScript
function describe(value) {
  if (Array.isArray(value)) {
    return "array";
  }
  return typeof value;
}

console.log(describe([1, 2]));

Array.isArray(value) gives true for an array and false for everything else. Now line 2 is true, and the program prints array.

Check for the exact kind you need

typeof gives a first, rough answer. It says "object" for arrays and for plain objects alike. So when you need to know "is this an array?", ask that exact question with Array.isArray.

Check a list from an appPop out in the code editor (opens in a new tab)JavaScript
function describeList(value) {
  if (value === null) return "No list yet";
  if (!Array.isArray(value)) return "Not a list";
  return value.length + " items";
}

console.log(describeList(["tea", "bread"]));
console.log(describeList(null));
console.log(describeList("tea"));

The function describeList checks a value before it uses the value as a list:

  • Line 2: if the value is null, the list hasn't arrived yet. It gives back "No list yet".
  • Line 3: the ! means "not". If the value is not an array, it gives back "Not a list".
  • Line 4 runs only for an array. value.length is the number of items in the array.

Lines 7 to 9 print 2 items, No list yet, and Not a list.

Pick the check that matches your question. Read each row of the table as: "to answer this question, write this check."

Which check answers which question
Your questionThe check to writeWhat does it tell apart?
Is this text?typeof value === "string"It tells strings apart from all other values.
Is this a list?Array.isArray(value)It tells arrays apart from other objects.
Was it left empty on purpose?value === nullIt tells null apart from all other values.
Can I call this?typeof value === "function"It tells functions apart from all other values.

A profile page shows a user's name. Knowing "this is an object" is not enough. The page also needs a name property, and that name must be text.

Check a profile before you show itPop out in the code editor (opens in a new tab)JavaScript
function displayProfile(profile) {
  if (profile === null || typeof profile !== "object" || Array.isArray(profile)) {
    return "No profile";
  }
  if (typeof profile.name !== "string") {
    return "Unknown user";
  }
  return profile.name;
}
console.log(displayProfile({ name: "Asha" }));
console.log(displayProfile({}));
console.log(displayProfile(null));
  • Lines 2 to 4 give back "No profile" if the value is null, is not an object, or is an array. Here !== means "is not exactly".
  • Lines 5 to 7 give back "Unknown user" if name is not text.
  • Line 8 runs only when both checks pass. It gives back the name.
  • Lines 10 to 12 print Asha, Unknown user, and No profile.

Do these checks where data comes into your code from outside, like from a form or a server. Knowing the type can't tell you that an object has every property your page needs, so check each property you use. When you made the value yourself a few lines earlier, you usually don't need the checks.

Dynamic typing

STEP THROUGH

JavaScript is dynamically typed. This means a variable doesn't have a fixed type. A let variable can hold a number now, text later, and true after that. The type always belongs to the value the variable holds right now.

Real-life analogyThe label is on the thing inside the box

Picture a box with the name value written on it. The box name never changes. The thing inside has its own label that says what kind of thing it is. Put in 42, and the label says "number". Swap in "forty-two", and the label says "string".

In real life: A box with the name value
In JavaScript: The variable value
In real life: The label on the thing inside
In JavaScript: The type of the value
In real life: Swap a toy for a book
In JavaScript: Store a value of a different type
The same box, value, at three moments. First it holds 42, a number. Then it holds forty-two in quotes, a string. Then it holds true, a boolean.let value = 4242valuenumbervalue = "forty-two""forty-two"valuestringvalue = truetruevalueboolean
It's the same box, value, each time. Only the card inside changes. typeof value looks at the card that is in the box right now.
One variable holds different types over time
Step 0 of 6Ready
Your turn: follow the blue line

Watch one variable hold a number, then text, then a boolean. Each typeof gives the type of the value inside right now.

Running in
  1. script
Next: line 1
console.log(typeof value);value = "forty-two";console.log(typeof value);value = true;console.log(typeof value);
CallStoreChangeResultBlue line: runs next. Ran: already executed.
Recent returnsNothing yet. Start with the blue line.
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.

Press Step to run each line. Each typeof line prints the type of the value stored just before it: number, then string, then boolean.

Dynamic typing makes small programs quick to write. But you have to keep track of what kind of value your code expects. TypeScript, a later lesson, is a language built on top of JavaScript. In TypeScript you write down the type each variable should hold, and your editor warns you about mistakes before the program runs.

Watch out: a value can look like a number and still be text. If price holds "3", it holds a string, not the number 3. Clear variable names and small checks where data comes in help you spot this.

Where you’ll use this

You check types when your code gets a value from outside. For example:

  • what a person typed into a form,
  • a setting that was saved earlier,
  • data sent to your page by a server.

The examples here are small, but real apps use the same checks.

Describe any value safelyPop out in the code editor (opens in a new tab)JavaScript
function describeValue(value) {
  if (Array.isArray(value)) return "array";
  if (value === null) return "null";
  return typeof value;
}

console.log(describeValue(["Ada", "Lin"]));
console.log(describeValue(null));

Lines 2 and 3 handle the two values where typeof gives a confusing answer: arrays and null. Line 4 runs for every other value and gives back the typeof answer. Lines 7 and 8 print array and null. A later lesson, Checking types reliably, builds a fuller version.

Turn a form value into a checked numberPop out in the code editor (opens in a new tab)JavaScript
function readQuantity(text) {
  const quantity = Number(text);
  if (text.trim() === "" || !Number.isFinite(quantity)) {
    return "Enter a number";
  }
  return quantity;
}

console.log(readQuantity("3"));
console.log(readQuantity(""));
console.log(readQuantity("tea"));

A form box always gives your code text, even when a person types a number. So 3 arrives as the string "3". The function readQuantity turns it into a number and checks it:

  • Line 2: Number(text) turns the text into a number. Number("3") gives 3. Number("tea") gives NaN.
  • Line 3 checks two things. text.trim() removes spaces from both ends of the text, so text.trim() === "" is true for an empty box. Number.isFinite(quantity) is true only for a normal number, not for NaN or Infinity. The ! in front means "not".
  • Line 4 gives back "Enter a number" if the box was empty or the text wasn't a number.
  • Line 6 gives back the number.

Lines 9 to 11 print 3, Enter a number, and Enter a number. The empty check matters, because Number("") gives 0. Without it, an empty box would count as zero.

A copy can still share the object insidePop out in the code editor (opens in a new tab)JavaScript
const original = { user: { name: "Asha" } };
const copy = { ...original };
copy.user.name = "Lin";
console.log(original.user.name);
  • Line 1 makes an object, original. Its property user holds another object. An object inside another object is called a nested object.
  • Line 2 uses spread syntax, the three dots ..., to copy the properties of original into a new object, copy. But it copies only the top level. For user, it copies the reference, not the object. This is called a shallow copy.
  • So copy.user and original.user point to the same object. Line 3 changes the name through copy.
  • Line 4 reads the name through original and prints Lin.

A shallow copy is fine when the object has no objects inside it. If the inner objects must be separate too, copy them as well.

Common mix-ups

Each card below shows a common wrong idea, then what is really true.

"typeof tells me the exact kind of every value."

It gives only broad answers. Arrays, dates, and plain objects all give "object". When you need the exact kind, use a specific check like Array.isArray.

"null is an object."

null is a primitive. typeof null says "object" only because of an old mistake that JavaScript keeps.

"const makes an object unchangeable."

const only stops you from putting a new value in the variable. The object itself can still change: after const box = { n: 1 }, you can still write box.n = 2.

"Copying an object variable makes a new object."

It copies only the reference. Both variables point to the same object, until you make a real copy.

"NaN has its own type."

NaN is a value of the number type. It means a math step failed. It is not a ninth type.

"A value that looks like a number is a number."

Form input "3" is a string. Turn it into a number with Number(). Then check it with Number.isFinite when you need a normal number.

"{ ...object } copies everything inside an object."

Spread copies only the top level. Objects inside it are still shared until you copy them too.

Practice: spot the type

5 EXERCISES

Guess the answer before you run any code. Start with the warm-ups. If you get stuck, open a hint.

Exercise 1 · Warm-upPredict what typeof prints

Each line prints what typeof gives back for one value. Write the four printed lines in order.

Starter codePop out in the code editor (opens in a new tab)JavaScript
console.log(typeof 42);
console.log(typeof null);
console.log(typeof [1, 2]);
console.log(typeof NaN);

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

    Exercise 2 · PracticeFix the check for a user list

    A profile page gets a list of users from an API: a service on a server that sends data to your page. The data might be an array, null, or some other value. Line 2 has a broken check. What should replace typeof value === "array" so that the function says "array" only for arrays?

    Starter codePop out in the code editor (opens in a new tab)JavaScript
    function describe(value) {
      if (typeof value === "array") {
        return "array";
      }
      return typeof value;
    }
    
    console.log(describe([1, 2]));

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

      Exercise 3 · PracticeIs Math a primitive or an object?

      Math is built into JavaScript. It holds math helpers like Math.round. Is Math a primitive or an object?

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

        Exercise 4 · PracticeExplain the changed copy

        What does line 4 print? Then explain in your own words why.

        Starter codePop out in the code editor (opens in a new tab)JavaScript
        const box1 = { n: 1 };
        const box2 = box1;
        box2.n = 2;
        console.log(box1.n);

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

          Exercise 5 · ChallengeCount the primitive types

          How many primitive types does JavaScript have? Try to name them all from memory first.

          Starter codePop out in the code editor (opens in a new tab)JavaScript
          console.log(["string", "number", "bigint", "boolean", "undefined", "symbol", "null"].length);

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

            Quiz: check your understanding

            7 QUESTIONS

            Each answer says why it is right or wrong. For a question with code, guess the output first, then choose.

            Lesson quiz · 7 questionsScore: first tries count
            1. Question 1 of 7Which sentence describes a primitive value?

              Choose an answer to see the explanation.

            2. Question 2 of 7This code copies a number into b, then changes b. What does it print?

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

              Choose an answer to see the explanation.

            3. Question 3 of 7Which list holds only primitive types?

              Choose an answer to see the explanation.

            4. Question 4 of 7What does typeof null print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(typeof null);

              Choose an answer to see the explanation.

            5. Question 5 of 7How should you check whether a value is an array?

              Choose an answer to see the explanation.

            6. Question 6 of 7The variable gets a number, then text. What does this print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              let value = 42;
              value = "forty-two";
              console.log(typeof value);

              Choose an answer to see the explanation.

            7. Question 7 of 7What does typeof NaN print?

              Read the code, then predictPop out in the code editor (opens in a new tab)JavaScript
              console.log(typeof NaN);

              Choose an answer to see the explanation.

            Key takeaways

            • JavaScript has eight types: seven primitive types and the object type.
            • You can't change a primitive; you can only replace it. Copying a primitive makes a separate value.
            • Copying an object variable copies only the reference. Both variables then point to the same object.
            • typeof gives a type name as text. Remember its surprises: null, arrays, functions, and NaN.
            • A variable has no fixed type. The type belongs to the value it holds right now.
            • Use Array.isArray to check for an array, and value === null to check for null.
            • A form always gives you text. Turn it into a number and check it before you use it as a number.

            Remember the one-liner.
            A value's type says what kind of value it is. The type decides how the value is copied, how you check it, and what you can do with it.

            Coming next: Numbers & math.

            CompleteFrontend Clear concepts. Working examples.