044: Values and Data Types
Outcomes
By the end of this lesson, you can:
- recognize string, number, Boolean,
undefined,null, object, and array values; - explain the difference between primitive and object values at a beginner level;
- inspect values with
typeofand identify its important exceptions; - choose a suitable type for realistic data; and
- avoid confusing a value's type with the variable that currently holds it.
Prerequisites and Retrieval
Retrieve const, let, initialization, reassignment, and block scope from 043.
- Which declaration should be the default?
- Which declaration permits a new assignment?
- Is
"42"visibly the same kind of literal as42?
Use a fresh browser console or module script. Predict every type before running the examples.
Terms
- data type: The classification of values: seven primitives plus Object. — Source: MDN: Data structures
- primitive: “Data that is not an object and has no methods”: string, number, bigint, boolean, undefined, symbol, null. — Source: MDN: Primitive
- string: An immutable sequence of characters representing text. — Source: MDN: String
- number: Double-precision 64-bit IEEE value including integers and NaN/Infinity. — Source: MDN: Number
- Boolean: Logical type with exactly two values: true and false. — Source: MDN: Boolean
- undefined: Value of a declared-but-uninitialized variable; also missing property access result. — Source: MDN: undefined
- null: A deliberate “no value” marker; typeof null returns "object" historically. — Source: MDN: null
- object: A collection of properties keyed by strings/symbols; arrays and functions are objects. — Source: MDN: Object
- array: An ordered list-like object with numeric indices starting at 0. — Source: MDN: Array
- dynamic typing: Types attach to values, so one variable can hold different types over time. — Source: MDN: Data structures
typeof: Operator returning a string describing a value’s type. — Source: MDN: typeof- Primitive (official): "A primitive is data that is not an object and has no methods; there are 7 primitives: string, number, bigint, boolean, undefined, symbol, null." — Source: MDN: Primitive
- Reference: "A reference is a pointer to an object in memory; copying a reference copies the pointer, not the object." — Source: MDN: Data structures — Objects
Beginner Explanation and Mental Model
Programs represent facts as values. Choosing a type is like choosing the correct container on a form. A name is text, a price is numeric, and an enrollment state is Boolean. Type matters because operations have meanings based on their operands: 10 + 5 calculates 15, while "10" + "5" joins text into "105".
JavaScript currently defines seven primitive types: string, number, Boolean, undefined, null, BigInt, and Symbol. Today's required set focuses on the first five. BigInt and Symbol solve specialized problems and are not needed for these beginner models. Everything else belongs to the object type. Arrays look and act like lists, but technically they are objects.
const userName = "Leela"; // string
const score = 88.5; // number
const passed = true; // boolean
let feedback; // undefined
const selectedContact = null; // null
const user = { name: "Leela" }; // object
const skills = ["HTML", "CSS"]; // array object
undefined commonly means "not supplied or not initialized." null is normally assigned deliberately to mean "known to be absent." They are different values: null === undefined is false. Do not use the string "null" or "undefined" to represent absence; those are ordinary text.
Primitive values behave as indivisible values for today's mental model. Objects group data and are handled through references. If two variables refer to the same object, mutation through one reference is visible through the other. Detailed object behavior comes later.
Inspecting types
typeof returns a string:
console.log(typeof "hello"); // string
console.log(typeof 12); // number
console.log(typeof false); // boolean
console.log(typeof undefined); // undefined
Two important exceptions must be memorized rather than "fixed":
console.log(typeof null); // object (historical behavior)
console.log(typeof [1, 2]); // object
console.log(Array.isArray([1, 2])); // true
Use value === null to test specifically for null, and Array.isArray(value) to identify arrays. typeof is still useful; it is simply not a complete classifier.
JavaScript is dynamically typed. The binding does not receive a permanent declared type:
let result = 10;
result = "complete";
This is legal, but changing a variable's meaning and type usually harms readability. Prefer one stable meaning per variable.
Worked Example: User Profile Values
Run this complete example:
const userName = "Nila";
const userAge = 20;
const isEnrolled = true;
let latestScore;
const contact = null;
const profile = { city: "Chennai" };
const subjects = ["HTML", "CSS", "JavaScript"];
console.log(userName, typeof userName);
console.log(userAge, typeof userAge);
console.log(isEnrolled, typeof isEnrolled);
console.log(latestScore, typeof latestScore);
console.log(contact, typeof contact);
console.log(profile, typeof profile);
console.log(subjects, typeof subjects);
console.log("Is subjects an array?", Array.isArray(subjects));
console.log("Is contact null?", contact === null);
Expected output (object formatting varies by browser):
Nila string 20 number true boolean undefined undefined null object {city: "Chennai"} object ["HTML", "CSS", "JavaScript"] object Is subjects an array? true Is contact null? true
Notice that typeof itself returns text such as "number". It does not modify the value. latestScore has no initializer, so let gives it the value undefined. contact is deliberately empty, so it is initialized to null. The object and array both produce "object", and the dedicated array check distinguishes them.
Intermediate Example: Validate a Data Shape
Use only simple Boolean checks here; branching is taught in 047 after coercion and operators. Focus on the type results:
const product = {
name: "Keyboard",
price: 1500,
inStock: true,
discount: null,
};
const tags = ["accessory", "input"];
const hasValidName = typeof product.name === "string";
const hasValidPrice = typeof product.price === "number";
const hasStockFlag = typeof product.inStock === "boolean";
const hasNoDiscount = product.discount === null;
const hasTagList = Array.isArray(tags);
console.log("Name valid:", hasValidName);
console.log("Price valid:", hasValidPrice);
console.log("Stock flag valid:", hasStockFlag);
console.log("No discount:", hasNoDiscount);
console.log("Tags valid:", hasTagList);
Expected output is five lines ending in true. Type checking does not prove all business validity. For example, -500 is still a number, and an empty string is still a string. Later validation combines type checks with range and content rules.
Also remember that NaN has type "number". It represents an invalid numeric result. Use Number.isNaN(value) when that distinction matters; do not compare with value === NaN, which is always false.
Optional Advanced Extension: Primitive Copy vs Shared Reference
let firstScore = 80;
let copiedScore = firstScore;
copiedScore = 95;
const firstList = ["HTML"];
const sharedList = firstList;
sharedList.push("CSS");
console.log(firstScore, copiedScore);
console.log(firstList);
console.log(firstList === sharedList);
Expected output:
80 95 ["HTML", "CSS"] true
Assigning a primitive copies its value for this practical model. Assigning an object copies a reference, so both bindings identify the same array. This is enough reference knowledge for today; deep and shallow copying comes later.
Interview focus: values, references, and ownership
JavaScript is pass-by-value. For a primitive, the value passed to a function is the primitive itself. For an object, the value passed is a copy of the reference to that object. This is why interview answers should avoid saying simply "objects are passed by reference": the parameter receives its own value, but that value points at the same object.
function change(score, user) {
score = 100;
user.name = "Mina";
user = { name: "Replacement" };
}
const score = 60;
const user = { name: "Ravi" };
change(score, user);
console.log(score); // 60: the parameter was reassigned
console.log(user.name); // Mina: both references reached the same object
The follow-up is usually: "How would you prevent the function from changing the
caller’s object?" Return a new object, or make an explicit copy at the boundary.
Do not promise that const solves this; const protects a binding from
reassignment, not the object it names.
function rename(user, name) {
return { ...user, name };
}
const nextUser = rename(user, "Leela");
console.log(nextUser === user); // false
This pass-by-value distinction also explains why changing a parameter's reference does not replace the caller's variable, while changing a property can be visible to the caller.
Deep Dive: Primitives, Identity, BigInt, and Symbol
Primitive values are immutable values. Objects are reference values with identity.
let first = "tea";
let second = first;
second = "coffee";
console.log(first); // "tea"
Compare that with an object:
const firstOrder = { total: 120 };
const secondOrder = firstOrder;
secondOrder.total = 150;
console.log(firstOrder.total); // 150
Both variables point to the same object.
BigInt
number is an IEEE-754 floating-point value. Very large integers can lose precision.
console.log(Number.MAX_SAFE_INTEGER); // 9007199254740991
const ledgerId = 9007199254740993n;
console.log(ledgerId + 1n);
Do not mix number and bigint in arithmetic without explicit conversion.
// 10n + 5 // TypeError
Number(10n) + 5;
Symbol
Symbols are unique primitive values, commonly used for collision-resistant property keys and language protocols.
const internalId = Symbol("internalId");
const order = {
number: "ORD-1001",
[internalId]: 8472,
};
console.log(order.number);
console.log(order[internalId]);
Symbol.iterator is especially important later because it defines how objects participate in for...of.
typeof edge cases worth remembering
typeof null; // "object" — historical quirk
typeof []; // "object"
Array.isArray([]); // true
typeof function () {}; // "function"
typeof 1n; // "bigint"
typeof Symbol(); // "symbol"
Use the inspection tool that matches the question you are actually asking.
Mistakes and Debugging
- Forgetting quotes:
const city = Chennai;looks for a variable namedChennai. Use"Chennai"for text. - Quoting numbers: a price of
"500"is text and may concatenate. Store numeric facts as500. - Quoting Booleans:
"false"is a non-empty string, not the Booleanfalse. - Assuming
typeof nullis"null": test withvalue === null. - Assuming arrays have
typeofresult"array": useArray.isArray(). - Treating
undefinedand undeclared as identical: an initialized/declared variable may containundefined; reading a completely undeclared name throwsReferenceError. - Using
typeofas full validation: combine it later with ranges, emptiness checks, and domain rules. - Relying on coercion: convert inputs explicitly at system boundaries instead of hoping operators infer intent.
Log both value and type while debugging: console.log("price", price, typeof price);. Check the earliest point where the actual type differs from the expected type.
Best Practices
- Model text as strings, quantities as numbers, states as Booleans, intentional absence as
null, and ordered collections as arrays. - Use lowercase
true,false,null, andundefined. - Prefer
nullonly when the application deliberately records absence; do not sprinkle it as a universal default. - Do not explicitly assign
undefinedunless an API contract requires it. - Use
Array.isArray()for arrays and strict equality fornull. - Keep each variable's meaning and expected type stable.
- Avoid wrapper objects such as
new Boolean(false)andnew String("text"); use primitives. - Treat browser form input as strings until explicitly validated and converted.
Tiered Exercises
Core
Create one value of each required type: string, number, Boolean, undefined, null, object, and array. Log each value and its typeof result. Use Array.isArray() for the list.
Practice
Model a book using a title, page count, availability flag, optional borrower, a small details object, and an array of genres. Choose types and print checks that prove your choices.
Professional Extension
Predict the results of typeof null, typeof [], Array.isArray({}), Array.isArray([]), typeof NaN, and null === undefined. Then verify and explain every result.
Complete Solutions
const textValue = "JavaScript";
const numberValue = 31;
const booleanValue = true;
let undefinedValue;
const nullValue = null;
const objectValue = { topic: "types" };
const arrayValue = [31, 32, 33];
console.log(textValue, typeof textValue);
console.log(numberValue, typeof numberValue);
console.log(booleanValue, typeof booleanValue);
console.log(undefinedValue, typeof undefinedValue);
console.log(nullValue, typeof nullValue);
console.log(objectValue, typeof objectValue);
console.log(arrayValue, typeof arrayValue, Array.isArray(arrayValue));
const title = "Clean Code Basics";
const pageCount = 240;
const isAvailable = true;
const borrower = null;
const details = { language: "English" };
const genres = ["technology", "education"];
console.log(typeof title === "string");
console.log(typeof pageCount === "number");
console.log(typeof isAvailable === "boolean");
console.log(borrower === null);
console.log(typeof details === "object" && details !== null);
console.log(Array.isArray(genres));
Every line prints true.
console.log(typeof null); // object: historical exception
console.log(typeof []); // object: arrays are objects
console.log(Array.isArray({})); // false
console.log(Array.isArray([])); // true
console.log(typeof NaN); // number
console.log(null === undefined); // false: different primitive values
Recap and Exit Questions
Types describe values and their behavior. Strings, numbers, Booleans, undefined, and null are primitives. Objects group data, and arrays are specialized objects. typeof is useful when its null and array exceptions are understood.
- Why should a price usually be a number rather than a numeric string?
- How do
undefinedandnulldiffer in intent? - What does
typeofreturn, and what type is that return value? - How should code detect an array?
- What does dynamic typing mean?
Official References
- MDN: JavaScript data types and data structures
- MDN: Grammar and types
- MDN:
typeof - MDN:
Array.isArray() - ECMA-262: ECMAScript language types
- MDN: Functions - arguments and parameters
References checked 2026-08-24.
