B Binance · The world's largest crypto exchangeBinance Sign up → AD OKX OKX · A leading global crypto exchangeOKX Sign up → AD
💻 Coding Basics · Lesson 6 / 10

Arrays and Objects — Storing and Handling Data

An array is an ordered list, and an object is a bundle where you find values by name (key). Put them together and an "array of objects" is just like a table: with loops and `map`, `filter` and `reduce` you can total it up and pick out the rows you want.

⏱ About 24 min ✍️ 5 practice questions 🧪 4 code exercises Updated 2026-10-09
🎯 By the end of this lesson you can
  • Read and add values with an array's index, length and push
  • Read and change object properties with dot notation and bracket notation
  • See an array of objects as a table and process it with loops or map, filter and reduce
  • Turn data into text and back with JSON.stringify and JSON.parse

1.Arrays — ordered lists

So far we have put one value in one variable. But you cannot store 30 students' scores in 30 variables. An array is a data type that holds several values in order under one name. You make one by listing values separated by commas inside square brackets, like [70, 85, 90]. The lists we took apart one by one with for...of in Lesson 4 were arrays.

You take values out of an array by their position number, the index. Indexes start at 0, not 1, so the first value is arr[0] and the second is arr[1]. The number of values is arr.length, and the index of the last value is always arr.length - 1. This is exactly where the off-by-one mistakes from Lesson 4 come from.

Reading an index that doesn't exist gives no error, just undefined. In an array of length 3, reading arr[3] or arr[-1] both give undefined. If you want to count from the end, arr.at(-1) gives the last value. You can mix numbers, strings and booleans in one array, but in practice arrays are easier to handle when they hold values of the same kind.

Indexes start at 0; a missing slot is undefined
const fruits = ['apple', 'pear', 'plum'];
console.log(fruits[0], fruits[2]);
console.log(fruits.length);
console.log(fruits[fruits.length - 1]);
console.log(fruits[3]);
console.log(fruits.at(-1));
Output
apple plum
3
plum
undefined
plum

2.Changing and searching arrays — `push`, `pop`, `includes`, `indexOf`

push adds a value to the end of an array, and pop takes the last value out, returning it and removing it from the array. You can also change a value by assigning to an index directly, as in arr[1] = 'grape'. Here is something easy to get confused about: even an array created with const can have its contents changed. What const prevents is "putting a different array into that name," not changing the slots inside the array.

To check whether a value is in an array, includes returns true or false and indexOf returns its position. indexOf returns -1 when it finds nothing — the same convention we used in Lesson 4 to mark "not found." So if you write if (arr.indexOf(x)), it is false when the value is in the first slot (0) and true when it is not found (-1) (truthy and falsy from Lesson 3). If you only want to know whether it is there, use includes.

Putting an array into another variable does not copy it; it creates one more name that points to the same array. In the code below, a push onto b changes a too. It is like two people sharing the address of the same house. If you really need a separate copy, spread it into a new array with [...a]. Objects behave exactly the same way.

push, pop, includes, indexOf
const cart = ['milk', 'bread'];
cart.push('eggs');
console.log(cart, cart.length);
const last = cart.pop();
console.log(last, cart);
console.log(cart.includes('bread'), cart.indexOf('bread'));
console.log(cart.indexOf('rice'));
Output
[ 'milk', 'bread', 'eggs' ] 3
eggs [ 'milk', 'bread' ]
true 1
-1
Two names pointing to the same array vs a copy made by spreading
const a = [1, 2];
const b = a;
b.push(3);
console.log(a);
const c = [...a];
c.push(4);
console.log(a, c);
Output
[ 1, 2, 3 ]
[ 1, 2, 3 ] [ 1, 2, 3, 4 ]

3.Objects — labeled slots

If arrays find values by "which position," objects find values by "which name." You make one by listing key: value pairs separated by commas inside curly braces, like { name: 'Alex', age: 20 }. Each key-value pair is called a property. Objects fit well when several pieces of information together describe one thing, such as one member or one product.

Properties are usually read with a dot, as in user.name, and when the key name is stored in a variable, with brackets, as in user[key]. Reading a property that doesn't exist gives undefined, just like a missing array slot. But if you then read a property from that undefined, you get a TypeError. The code below does exactly that; the cause is misspelling the key name as nmae. The exact wording of the message differs slightly between browsers.

This error is one of the most common ones you see when you plug AI-written code into real data. It usually happens when the key names in the data differ from the key names the code expected, or when some items are missing that property. The (reading 'length') in parentheses in the error message tells you what it failed to read, so trace back to find why the value just before it is undefined (Lesson 8).

Reading, changing and adding; a missing property is undefined
const user = { name: 'Alex', age: 20 };
console.log(user.name, user.age);
user.age = 21;
user.city = 'Boston';
console.log(user);
const key = 'name';
console.log(user[key]);
console.log(user.email);
Output
Alex 20
{ name: 'Alex', age: 21, city: 'Boston' }
Alex
undefined
Reading again from undefined gives a TypeError
const user = { name: 'Alex' };
console.log(user.nmae);
console.log(user.nmae.length);
Output
undefined
TypeError: Cannot read properties of undefined (reading 'length')

4.An array of objects = a table

Most real data comes in the shape of an "array of objects." Each slot of the array is a row of the table, and the object's keys are the column names. Think of it as one sheet of a spreadsheet such as Excel moved into code. The table and code below show the same fictional sales records in two ways.

In this shape, combining the loops of Lesson 4 with the property reading you just learned lets you do almost any calculation. Take out the rows one at a time (for...of), read the column you need (row.qty), and accumulate or count. In Lesson 9 you will turn a table written as text into this shape and compute totals, averages and totals per group yourself.

Fictional sales records — one row is one object
(index)`item``price``qty`
0notebook15004
1pencil50010
2eraser8003
ExampleIn the fictional sales records above, what is the total revenue (the sum of price × quantity)?
const sales = [
  { item: 'notebook', price: 1500, qty: 4 },
  { item: 'pencil', price: 500, qty: 10 },
  { item: 'eraser', price: 800, qty: 3 },
];
let revenue = 0;
for (const row of sales) {
  revenue += row.price * row.qty;
}
console.log(revenue);
Output
13400
  1. Step 1, what to accumulate: the revenue total. Starting value 0.
  2. Step 2, the work for one row: add row.price * row.qty. Notebook 6,000, pencil 5,000, eraser 2,400.
  3. Step 3, the result: 6,000 + 5,000 + 2,400 = 13,400 won.
  4. Check: there are 3 rows, so there should be 3 passes. Printing the running total for each row shows it growing 6000 → 11000 → 13400.
Answer13,400 won — accumulate price × quantity for each row

5.A first taste of `map`, `filter` and `reduce`

Arrays have methods that stand in for loops. The three most used are map, filter and reduce. All three take an arrow function like those in Lesson 5 and call it for each value in the array. map builds a new array from the transformed value of each item (same length), filter builds a new array of only the values for which the function returned true (same length or shorter), and reduce folds the values into one, such as a total.

The important point is that map and filter do not change the original array; they return a new one. This is the same property as the pure functions of Lesson 5, so the results are easy to predict. With reduce, always pass a starting value as the second argument. The 0 in reduce((s, x) => s + x, 0) corresponds to let sum = 0 in the running-total pattern of Lesson 4. Leave out the starting value and an empty array gives a TypeError.

At first a loop may be easier to read, and that's fine. These methods are just a shorter way to write what loops can do. However, AI-written code often chains these three together, so it is worth practicing reading such chains by breaking them into single steps and printing the intermediate results.

map transforms, filter picks, reduce folds — the original array stays the same
const prices = [1500, 500, 800, 12000];
const withTax = prices.map((p) => p * 1.1);
console.log(withTax.map((p) => Math.round(p)));
const cheap = prices.filter((p) => p < 1000);
console.log(cheap);
const total = prices.reduce((s, p) => s + p, 0);
console.log(total);
console.log(prices);
Output
[ 1650, 550, 880, 13200 ]
[ 500, 800 ]
14800
[ 1500, 500, 800, 12000 ]
Comparing the three methods
MethodWhat it doesWhat it returnsAs a loop
mapTransforms each valueA new array of the same lengthpush each transformed value into a new array
filterPicks values that meet a conditionA new array, same length or shorterpush only when the condition is true
reduceFolds into one valueA single value (a total, etc.)The running-total pattern

6.JSON — a text format for exchanging data

JSON is a format for writing objects and arrays as text (strings). Its name comes from JavaScript, but today almost every programming language and web service uses it to exchange data. Many configuration files, server responses and pieces of data that apps save are JSON. JSON.stringify turns a value into JSON text, and JSON.parse turns JSON text back into a value.

JSON looks like JavaScript object syntax but is stricter. Keys must be wrapped in double quotes, and strings may use only double quotes. A comma after the last item is not allowed, and comments are not allowed either. Functions and undefined cannot be stored, so when you stringify them they are dropped from object properties and turned into null inside arrays. Break even one rule and JSON.parse throws a SyntaxError.

JSON squeezed onto one long line is hard to read. Paste it into a JSON formatter tool and it will indent it for you, and it may also point out where the rules are broken. However, don't paste data containing personal information, such as real member records, into outside tools or AI; replace it with fictional data that has the same structure before checking it (Lesson 10).

Value → JSON text → back to a value
const item = {
  name: 'notebook',
  price: 1500,
  tags: ['office'],
};
const text = JSON.stringify(item);
console.log(text);
console.log(typeof text);
const back = JSON.parse(text);
console.log(back.price + 500);
Output
{"name":"notebook","price":1500,"tags":["office"]}
string
2000
The key has no quotes and single quotes are used — both break the JSON rules
const bad = "{ name: 'notebook' }";
console.log(JSON.parse(bad));
Output
SyntaxError: Expected property name or '}' in JSON at position 2 (line 1 column 3)
Pass 2 as the third argument, as in JSON.stringify(value, null, 2), and you get multi-line text indented by two spaces. The playground on this page shows multiple lines as they are, so try it when you print long data to inspect its structure.

📌 Key points

  • An array is an ordered list — indexes start at 0, the last is arr.length - 1, and a missing slot is undefined
  • An object is a bundle where you find values by name (key) — reading a property again from undefined gives a TypeError
  • Putting an array or object into another variable does not copy it; both names point to the same thing
  • An array of objects is a table — take out each row, read its columns and accumulate, or process it with map, filter and reduce
  • JSON means double-quoted keys and no trailing commas — stringify turns values into text, parse turns text into values

✍️ Practice questions

Answer first, then open "Answer and explanation".

Q1. Given const a = [10, 20, 30];, what is the value of a[a.length]?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ② undefined

a.length is 3, and indexes only go from 0 to 2, so a[3] is undefined. The last value is a[a.length - 1].

Q2. What is the result of const list = ['a', 'b']; list.push('c');?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ② list becomes ['a', 'b', 'c']

const only prevents putting a different value into the name. Changing the slots in the array or adding with push is allowed. push adds to the end.

Q3. What does [3, 8, 1, 6].filter((x) => x > 4) return?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ① [8, 6]

filter builds a new array of only the values for which the function returned true. You get an array of true/false values when you pass the same function to map.

Q4. Which of the following is valid JSON?

⭕ Correct

❌ Not quite — see the explanation

Answer and explanation
Answer ④ { "name": "Alex", "age": 20 }

In JSON, both keys and strings must use double quotes, and a comma after the last item is not allowed. The first has an unquoted key, the second uses single quotes, and the third has a trailing comma.

Q5. You got TypeError: Cannot read properties of undefined (reading 'price'). What should you check first?

Answer and explanation
Answer Why the value just before .price is undefined — check for a misspelled key name, a nonexistent index, or an item that is missing that property.

The error means "tried to read price from undefined." The problem is not price but the value before it (for example, items[i] or row.info).

🧪 Code lab

Write functions that read arrays and objects, and that accumulate and pick values from an array of objects (a table). Boundary values such as empty arrays are graded too.

Your code runs only inside an isolated sandbox in this browser and is never sent to a server. It has no network access and is stopped after 2 seconds. Edited code is saved only in this browser. Ctrl+Enter (⌘+Enter) runs it; Tab inserts two spaces (press Esc, then Tab, to move on).

JavaScript is off, so the code can't run here, but you can still read each task, its starter code, the automatic checks and a sample solution.

1Get the last value

Write a function lastItem(arr) that returns the last value of the array arr. For an empty array, return null.

Automatic checks
  • lastItem([1,2,3])expected 3
  • lastItem(["apple"])expected "apple"
  • lastItem([])expected null
  • lastItem([0,false])expected false
💡 Hint

In an empty array, arr[arr.length - 1] is arr[-1], which is undefined. That is why the empty array is handled separately first.

Show a sample solution
function lastItem(arr) {
  if (arr.length === 0) {
    return null;
  }
  return arr[arr.length - 1];
}

2Total quantity

Write a function totalQty(rows) that takes an array rows of objects shaped like { item, qty } and returns the sum of qty. For an empty array, return 0.

Automatic checks
  • totalQty([{"item":"notebook","qty":4},{"item":"pencil","qty":10}])expected 14
  • totalQty([])expected 0
  • totalQty([{"item":"eraser","qty":3}])expected 3
  • totalQty([{"item":"a","qty":0},{"item":"b","qty":0}])expected 0
💡 Hint

Each row is an object. Read row.qty with dot notation. You can also write it on one line with reduce.

Show a sample solution
function totalQty(rows) {
  let total = 0;
  for (const row of rows) {
    total += row.qty;
  }
  return total;
}

3Pick only the names that match

Write a function namesFrom(rows, min) that takes an array rows of objects shaped like { item, price } and a minimum price min, and returns an array of only the item values of rows whose price is min or more, in their original order. If no row matches, return an empty array [].

Automatic checks
  • namesFrom([{"item":"notebook","price":1500},{"item":"pencil","price":500},{"item":"bag","price":20000}], 1000)expected ["notebook","bag"]
  • namesFrom([], 100)expected []
  • namesFrom([{"item":"pencil","price":500}], 500)expected ["pencil"]
  • namesFrom([{"item":"pencil","price":500}], 501)expected []
💡 Hint

It takes two steps: pick the rows with filter, then pull out just the names with map. Using a loop with if and push works too.

Show a sample solution
function namesFrom(rows, min) {
  return rows
    .filter((r) => r.price >= min)
    .map((r) => r.item);
}

4Count each item

Write a function countBy(words) that takes an array of strings words and returns an object holding how many times each word appeared. Example: ['apple', 'pear', 'apple'] → { apple: 2, pear: 1 }. For an empty array, return an empty object {}.

Automatic checks
  • countBy(["apple","pear","apple"])expected {"apple":2,"pear":1}
  • countBy([])expected {}
  • countBy(["a"])expected {"a":1}
  • countBy(["x","x","x","y"])expected {"x":3,"y":1}
💡 Hint

The key name is in the variable w, so use brackets, counts[w], not dot notation. A word seen for the first time is undefined.

Show a sample solution
function countBy(words) {
  const counts = {};
  for (const w of words) {
    if (counts[w] === undefined) {
      counts[w] = 1;
    } else {
      counts[w] += 1;
    }
  }
  return counts;
}

🤖 Try asking AI like this

Copy a prompt and replace the [ ] parts with your own situation. Don't take the answer on trust — check it against this lesson.

When you're unsure how to store data in arrays and objects

Turn the following fictional data into a JavaScript "array of objects." Use lowercase English key names, and make numbers actual numbers, not strings. Then show 3 calculations you could do with this data (a total, picking rows by a condition, counting per group), with a loop version and a `map`/`filter`/`reduce` version side by side. Data: [paste a fictional table]

When code that chains `map`, `filter` and `reduce` is hard to read

Break the `map`/`filter`/`reduce` chain in the code below into single steps, and use a small example input to show what array or value each step produces. Also write a `for...of` loop version that does the same thing. Code: [paste here]

When `JSON.parse` throws an error

Find every rule violation (quotes, trailing commas, comments, etc.) that makes the following JSON string fail in `JSON.parse`. Also show the corrected JSON. The content is fictional example data: [paste here]

🧰 Related tools

Tools for checking and tidying the JSON, regular expressions and text from this lesson. Don't paste real personal data or passwords.

References
  • MDN Web Docs — JavaScript Guide: Indexed collections, Working with objects
  • MDN Web Docs — reference for Array.prototype.map / filter / reduce and JSON.stringify / JSON.parse
  • General rules of the ECMA-404 JSON data interchange syntax standard

Reached every goal above? Mark the lesson complete.

💻 Coding Basics

  1. 1What Is a Program? — Breaking Work into Sequence, Choice, and Repetition
  2. 2Values, Variables, and Types — Putting Name Tags on Values
  3. 3Conditionals — Taking Different Paths Depending on the Situation
  4. 4Loops — Doing the Same Thing Many Times, Exactly
  5. 5Functions — Splitting Work into Small Named Machines
  6. 6Arrays and Objects — Storing and Handling Data
  7. 7Strings and Text — Cutting, Finding and Replacing Characters
  8. 8Debugging and Reading Errors — Turning Red Text into Clues
  9. 9Simple Automation — Spreadsheet Math and Text Cleanup in Code
  10. 10Reading and Verifying AI-Written Code — Tests, Security, Licenses, Privacy
📚 Worth reading
📊Using AI for Spreadsheets, and Checking the Formulas→ 💻AI Coding Assistants: Security and Licence Risks→ 💬Practising Conversation in a Foreign Language with AI→ ⚙️Finding Work Tasks Worth Automating with AI→
← Foundations for the AI Era