By WebNest Studio Engineering Team
JavaScript Tutorial
JavaScript Arrays and Objects
Arrays and objects are the two core structures JavaScript uses to group related data. Arrays are ordered collections indexed by number, ideal for lists of similar items; objects are unordered collections of key-value pairs, ideal for representing a single entity with named properties.
Modern JavaScript adds powerful tools for working with both: a rich set of array iteration methods, destructuring for pulling values out of structures concisely, and the spread operator for copying and combining them.
Why it matters
Data from an API arrives as arrays of objects, and turning it into what the page needs is the daily work of front-end development. map, filter and reduce, with destructuring and the spread operator, replace most loops and are the style in which React code is written.
Array Iteration Methods: map, filter, reduce, forEach
These four methods are the backbone of modern array processing in JavaScript, and each has a distinct purpose.
forEach— runs a function once per element for side effects (like logging); it always returnsundefined.map— transforms each element and returns a new array of the same length containing the results.filter— returns a new array containing only the elements for which the callback returns true.reduce— combines all elements into a single accumulated value, using a callback that receives the running total and the current element.
Object Literals
An object literal groups related values under named keys: const user = { name: "Ana", age: 30 };. Properties are accessed with dot notation (user.name) or bracket notation (user["name"]), the latter being required when the key is dynamic or not a valid identifier.
Destructuring
Destructuring lets you unpack values from arrays or properties from objects into distinct variables in one step. Array destructuring uses position: const [first, second] = [10, 20];. Object destructuring uses key names: const { name, age } = user;, and can rename or provide defaults: const { name: userName = "Guest" } = user;.
The Spread Operator
The spread operator (...) expands an array or object into its individual elements or properties. It is commonly used to copy structures without mutating the original (const copy = [...original];), merge multiple arrays or objects (const merged = { ...defaults, ...overrides };), or pass an array's elements as individual function arguments.
Examples
map, filter, and reduce chained to process a list of prices
const prices = [10, 25, 40, 15, 60];
const discounted = prices
.filter((price) => price >= 20)
.map((price) => price * 0.9);
const total = discounted.reduce((sum, price) => sum + price, 0);
console.log(discounted);
console.log(total);
[ 22.5, 36, 54 ]
112.5
Destructuring and the spread operator together
const user = { name: "Ana", age: 30, city: "Lisbon" };
const { name, city, country = "Portugal" } = user;
console.log(name, city, country);
const [first, , third] = [1, 2, 3];
console.log(first, third);
const updatedUser = { ...user, age: 31 };
console.log(updatedUser);
const combined = [...[1, 2], ...[3, 4]];
console.log(combined);
Ana Lisbon Portugal
1 3
{ name: 'Ana', age: 31, city: 'Lisbon' }
[ 1, 2, 3, 4 ]
Common Mistakes
- Using "forEach" and expecting its return value to be a transformed array — forEach always returns undefined; use "map" instead.
- Forgetting to provide an initial value to "reduce" and getting incorrect results (or an error on an empty array) because the first element is used as the accumulator by default.
- Mutating an array or object directly with the spread operator, mistakenly believing spread performs a deep copy — it only creates a shallow copy, so nested objects are still shared by reference.
- Mismatching the order of destructured array variables and expecting them to match by name instead of position.
Exercise
From the list of products, print the names of those that cost more than 100, joined with a comma and a space. Then print the total of all prices. Then use destructuring to take the name and price of the first product and print them on one line.
Expected output: bag, book, 612, pen 12 (one per line)
const products = [
{ name: "pen", price: 12 },
{ name: "bag", price: 450 },
{ name: "book", price: 150 },
];
// TODO: names of products over 100, joined with ", "
// TODO: total of all prices
// TODO: destructure name and price from the first product and log them
Show hints
- Chain
filterandmap, then calljoin(", "). reduce((sum, p) => sum + p.price, 0)adds the prices, andconst { name, price } = products[0]destructures.
Show solution
const products = [
{ name: "pen", price: 12 },
{ name: "bag", price: 450 },
{ name: "book", price: 150 },
];
const expensive = products.filter((p) => p.price > 100).map((p) => p.name);
console.log(expensive.join(", "));
const total = products.reduce((sum, p) => sum + p.price, 0);
console.log(total);
const { name, price } = products[0];
console.log(name + " " + price);
Quick quiz
1. What does map return?
- A. The original array, modified
- B. A new array of the same length, holding the result of the function for each item
- C. undefined
- D. A single value
Show answer
B. map does not change the original array.
2. What is the difference between forEach and map?
- A. forEach returns undefined and is used for side effects; map returns a new array
- B. There is none
- C. forEach is faster
- D. map changes the original array
Show answer
A. Use map when you need the transformed values, forEach when you only need to do something for each item.
3. What does const copy = [...items]; create?
- A. A second name for the same array
- B. A deep copy
- C. A string
- D. A new array containing the same elements: a shallow copy
Show answer
D. Objects inside the array are still shared between the two arrays.
Interview questions
Explain map, filter and reduce.
Show answer
map applies a function to every element and returns a new array of the results, the same length as the original. filter returns a new array with only the elements for which the function returns true. reduce combines all the elements into a single value, carrying an accumulator from one call to the next. None of them changes the original array, and they can be chained.
What is the difference between a shallow copy and a deep copy?
Show answer
A shallow copy, made with the spread operator or Object.assign, creates a new outer object or array, but nested objects are still shared with the original, so changing one changes both. A deep copy duplicates every level. structuredClone(value) makes a deep copy of most data; the older JSON.parse(JSON.stringify(value)) works for plain data but loses dates, functions and undefined.
Key Points to Remember
- forEach performs side effects and returns undefined; map transforms; filter selects; reduce accumulates into one value.
- Object properties can be accessed with dot notation or bracket notation; bracket notation is required for dynamic keys.
- Destructuring unpacks array elements by position and object properties by key, and supports defaults and renaming.
- The spread operator creates shallow copies and merges arrays/objects; nested structures are still shared by reference.
Practice in the playground
Write and run your own code for this topic, or start from the exercise or an example. Shows a live preview of your HTML, CSS and JavaScript. Your code for each topic is kept in this browser.
Run the examples
Change an input, predict the result, then compare it with the output. Explain why the result changes.
Written by
WebNest Studio Engineering Team
Practical lessons from developers working with Java, Python, React, databases and production systems.
Led by Vansh Duggal, Founder, WebNest Studio · Full-stack & software engineering