JavaScript Fundamentals: Objects and Arrays
Objects and arrays are the workhorses of JavaScript. Whether you’re storing user data, handling form submissions, or processing API responses, you’ll reach for these data structures constantly. This JavaScript fundamentals tutorial teaches you how to create, manipulate, and choose between objects and arrays.
What are objects?
An object is a collection of key-value pairs. Keys (also called properties) are strings or Symbols, while values can be anything—strings, numbers, functions, even other objects.
Creating objects
The most common way to create an object is with curly braces:
const user = {
name: "Sarah",
age: 28,
isDeveloper: true
};
console.log(user.name); // "Sarah"
console.log(user["age"]); // 28
You can also use the Object constructor, though curly braces are preferred:
const empty = new Object(); // Rarely used
Adding and modifying properties
Objects are mutable. You can add or change properties anytime:
const person = { name: "Alex" };
// Add new property
person.city = "London";
person["country"] = "UK";
// Modify existing
person.name = "Alexander";
console.log(person);
// { name: "Alexander", city: "London", country: "UK" }
Methods
When a property holds a function, it’s called a method. Methods give objects behavior:
const calculator = {
a: 0,
b: 0,
setValues(x, y) {
this.a = x;
this.b = y;
},
add() {
return this.a + this.b;
},
multiply() {
return this.a * this.b;
}
};
calculator.setValues(5, 3);
console.log(calculator.add()); // 8
console.log(calculator.multiply()); // 15
Object destructuring
Destructuring lets you extract properties into variables:
const product = {
name: "Laptop",
price: 999,
inStock: true
};
// Old way
const name = product.name;
const price = product.price;
// Destructuring
const { name, price } = product;
console.log(name, price); // "Laptop" 999
What are arrays?
An array is an ordered collection of values. Each value has a numeric index starting from 0. Arrays can hold mixed types.
Creating arrays
const fruits = ["apple", "banana", "cherry"];
const numbers = [1, 2, 3, 4, 5];
const mixed = [1, "hello", true, null];
console.log(fruits[0]); // "apple"
console.log(fruits.length); // 3
Adding and removing elements
const colors = ["red", "blue"];
// Add to end
colors.push("green");
colors.push("yellow");
// Add to beginning
colors.unshift("purple");
// Remove from end
const last = colors.pop();
// Remove from beginning
const first = colors.shift();
console.log(colors); // ["blue", "green"]
console.log(first, last); // "purple" "yellow"
Iterating arrays
There are several ways to loop through arrays:
const scores = [85, 92, 78, 90];
// for loop
for (let i = 0; i < scores.length; i++) {
console.log(scores[i]);
}
// forEach
scores.forEach((score, index) => {
console.log(`Score ${index}: ${score}`);
});
// for...of (modern)
for (const score of scores) {
console.log(score);
}
Essential array methods
map() — transform each element
map() creates a new array by transforming each element:
const prices = [100, 200, 300];
// Add tax
const withTax = prices.map(price => price * 1.2);
console.log(withTax); // [120, 240, 360]
// Return objects
const items = ["apple", "banana"];
const objects = items.map((item, i) => ({
id: i + 1,
name: item
}));
// [{ id: 1, name: "apple" }, { id: 2, name: "banana" }]
filter() — keep matching elements
filter() creates a new array with elements that pass a test:
const numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9, 10];
const even = numbers.filter(n => n % 2 === 0);
console.log(even); // [2, 4, 6, 8, 10]
const users = [
{ name: "Alice", age: 25 },
{ name: "Bob", age: 17 },
{ name: "Charlie", age: 30 }
];
const adults = users.filter(user => user.age >= 18);
console.log(adults);
// [{ name: "Alice", age: 25 }, { name: "Charlie", age: 30 }]
reduce() — combine into single value
reduce() shrinks an array into a single value:
const numbers = [1, 2, 3, 4, 5];
const sum = numbers.reduce((acc, num) => acc + num, 0);
console.log(sum); // 15
// Find maximum
const max = numbers.reduce((a, b) => a > b ? a : b);
console.log(max); // 5
// Group by property
const people = [
{ name: "Alice", dept: "Engineering" },
{ name: "Bob", dept: "Sales" },
{ name: "Charlie", dept: "Engineering" }
];
const byDept = people.reduce((acc, person) => {
if (!acc[person.dept]) {
acc[person.dept] = [];
}
acc[person.dept].push(person.name);
return acc;
}, {});
console.log(byDept);
// { Engineering: ["Alice", "Charlie"], Sales: ["Bob"] }
find() and findIndex()
Find the first matching element:
const products = [
{ id: 1, name: "Laptop", price: 999 },
{ id: 2, name: "Phone", price: 599 },
{ id: 3, name: "Tablet", price: 449 }
];
const found = products.find(p => p.price < 500);
console.log(found); // { id: 3, name: "Tablet", price: 449 }
const index = products.findIndex(p => p.name === "Phone");
console.log(index); // 1
Some and Every
Check conditions across the array:
const scores = [85, 92, 78, 90];
const allPassing = scores.every(s => s >= 70);
console.log(allPassing); // true
const hasPerfect = scores.some(s => s === 100);
console.log(hasPerfect); // false
includes()
Check if an array contains a value:
const fruits = ["apple", "banana", "cherry"];
console.log(fruits.includes("banana")); // true
console.log(fruits.includes("grape")); // false
When to use objects vs arrays
Use arrays when:
- Order matters (lists, sequences)
- You need to iterate through all elements
- You’re working with collections of similar items
- You need index-based access
const tasks = ["Buy groceries", "Call dentist", "Finish report"];
// Order is important—first task is index 0
Use objects when:
- You need named keys (associative data)
- You’re mapping identifiers to values
- You need fast lookup by key
- Data has fixed, known properties
const user = {
id: 123,
name: "Sarah",
email: "sarah@example.com"
};
// Fast lookup: user.id, user.name
Combining both
Real code often mixes objects and arrays:
const orders = [
{
id: 1,
customer: { name: "Alice", email: "alice@test.com" },
items: ["Widget", "Gadget"],
total: 149.99,
status: "shipped"
},
{
id: 2,
customer: { name: "Bob", email: "bob@test.com" },
items: ["Gadget"],
total: 49.99,
status: "pending"
}
];
// Find all shipped orders
const shipped = orders.filter(o => o.status === "shipped");
// Get customer names
const customers = orders.map(o => o.customer.name);
// ["Alice", "Bob"]
Spread operator with objects and arrays
The spread operator (...) copies and combines:
// With arrays
const nums = [1, 2, 3];
const more = [4, 5, 6];
const combined = [...nums, ...more];
console.log(combined); // [1, 2, 3, 4, 5, 6]
// With objects
const defaults = { theme: "light", language: "en" };
const userPrefs = { theme: "dark" };
const settings = { ...defaults, ...userPrefs };
// { theme: "dark", language: "en" }
Modern array features
Array Destructuring
const colors = ["red", "green", "blue", "yellow"];
const [first, second] = colors;
console.log(first, second); // "red" "green"
const [head, ...rest] = colors;
console.log(rest); // ["green", "blue", "yellow"]
at() — negative indexing
const items = ["a", "b", "c", "d"];
console.log(items.at(-1)); // "d" (last element)
console.log(items.at(-2)); // "c" (second to last)
flat() and flatMap()
const nested = [1, [2, [3, [4]]]];
console.log(nested.flat(2)); // [1, 2, 3, [4]]
console.log(nested.flat(Infinity)); // [1, 2, 3, 4]
// flatMap combines map and flat
const words = ["hello", "world"];
const chars = words.flatMap(word => word.split(""));
console.log(chars); // ["h", "e", "l", "l", "o", "w", "o", "r", "l", "d"]
Summary
Choosing between objects and arrays
Objects and arrays often show up together, but they solve different problems. An object is best when you care about names: a user record, a settings object, or a lookup table keyed by something meaningful. An array is best when order matters: a list of items, a queue of tasks, or a result set that you want to process from start to finish. The right choice makes code easier to read because the structure matches the way the data is used.
It is also worth thinking about how the data will change over time. Arrays are strong when you need to add, remove, sort, or map over a sequence. Objects are stronger when you need direct access by key and when the shape is fixed enough to describe with property names. If you find yourself searching through an array to find one item by an ID on every pass, that may be a sign that an object or Map would be a better fit.
Working with nested data
Real application data is rarely flat. A user may have addresses, orders, and preferences, while each order may have line items and shipping details. Objects and arrays nest naturally, so it helps to read the structure before writing code against it. Start by identifying which parts are single values and which parts are collections. That makes destructuring, mapping, and filtering much easier to reason about later.
When nested data gets deep, keep the transformation steps small. Pull out one level, then work on the next. That keeps the code more understandable than a giant expression that does everything at once. It also makes debugging simpler because you can log each stage and see where the shape changes. In practice, that habit pays off whenever you are cleaning API responses, shaping form data, or preparing state for display.
Data shape and intent
The best JavaScript data structures communicate intent. If the key names matter, use an object. If position matters, use an array. If both matter, combine them in a way that still reads clearly. That may mean an array of objects, an object whose values are arrays, or a small custom class when the behavior is more important than the raw structure. The point is not to force everything into one pattern, but to let the structure tell the truth about the data.
That truth is helpful for the people reading the code later. A clear structure reduces the amount of guesswork needed to understand a function, and it usually makes testing easier too. The same principle applies when you are preparing data for rendering or for storage. If the shape is obvious, the code that consumes it becomes easier to trust.
Objects store data as key-value pairs—perfect for records with named properties. Arrays store ordered collections—ideal for lists and sequences. Master these fundamentals, and you’ll handle most JavaScript data with confidence.
Key takeaways:
- Use objects for associative data with named keys
- Use arrays for ordered collections
map(),filter(), andreduce()are essential array methods- The spread operator makes copying and combining easy
- You can nest objects and arrays for complex data structures
In the next tutorial, we’ll explore control flow—conditionals and loops that direct your program’s execution.
A final data shape note
One of the easiest ways to avoid confusion is to name objects and arrays by what they contain, not by how they were created. A users array, a settings object, or a cartItems list all tell the reader what to expect before the code even runs. That naming habit makes the rest of the logic easier to trust because the data shape is already visible in the variable name.
If you are not sure which structure to use, look at the operations you need most often. Searching by name points toward objects, while ordering and repeated iteration point toward arrays. That simple question usually gets you to the right choice fast and keeps the code easy to follow later.
Next steps
- Continue with JavaScript control flow to learn conditionals and loops
- Explore JavaScript functions and scope to build reusable logic on top of object and array data
- See how objects and arrays power DOM manipulation