Skip to content
Happy Programming Guide
Start learning
JavaScript

Arrays and Objects in JavaScript

The two structures JavaScript is built on: how to create, read, update and loop over each, plus copying, destructuring and the reference trap.

A person working on a laptop

Almost all JavaScript data is an array, an object, or some nesting of the two. An array is an ordered list you reach by position; an object is a set of named properties you reach by key. This guide covers both, the methods worth memorising, and the reference behaviour that causes the most confusing bugs beginners hit.

Arrays#

JavaScript
const fruits = ["apple", "pear", "plum"];

console.log(fruits[0]);        // apple - counting starts at zero
console.log(fruits.at(-1));    // plum  - last item
console.log(fruits.length);    // 3

fruits.push("fig");            // add to the end
fruits.pop();                  // remove from the end
fruits.unshift("cherry");      // add to the front
fruits.shift();                // remove from the front

Arrays can hold anything, including other arrays and objects, and the types can be mixed:

JavaScript
const mixed = [1, "two", true, null, [3, 4], { name: "Ana" }];

The array methods that matter#

JavaScript
const numbers = [4, 1, 9, 3];

numbers.map(n => n * 2);              // [8, 2, 18, 6]   - transform
numbers.filter(n => n > 3);           // [4, 9]          - keep some
numbers.find(n => n > 3);             // 4               - first match
numbers.findIndex(n => n > 3);        // 0
numbers.includes(9);                  // true
numbers.some(n => n > 8);             // true
numbers.every(n => n > 0);            // true
numbers.reduce((sum, n) => sum + n, 0);  // 17
numbers.join(", ");                   // "4, 1, 9, 3"

Some methods change the original array and some return a new one. That distinction causes real bugs:

Changes the original Returns a new array
push, pop, shift, unshift map, filter, slice, concat
sort, reverse, splice toSorted, toReversed, with
JavaScript
const original = [3, 1, 2];

const sorted = original.sort();       // original is now [1, 2, 3] too
const safe = [...original].sort();    // original untouched
const modern = original.toSorted();   // same, newer syntax

Objects#

JavaScript
const person = {
  name: "Ana",
  age: 34,
  greet() {
    return "Hello, " + this.name;
  },
};

console.log(person.name);        // dot notation
console.log(person["age"]);      // bracket notation

person.city = "Leeds";           // add
person.age = 35;                 // update
delete person.city;              // remove

console.log("name" in person);   // true
console.log(person.email);       // undefined - no error

Use brackets when the key is in a variable, or is not a valid identifier:

JavaScript
const field = "age";
console.log(person[field]);       // 34
console.log(person["first name"]); // spaces need brackets

Looping#

JavaScript
// Arrays
for (const fruit of fruits) console.log(fruit);
fruits.forEach((fruit, index) => console.log(index, fruit));
for (const [i, fruit] of fruits.entries()) console.log(i, fruit);

// Objects
for (const key of Object.keys(person)) console.log(key);
for (const value of Object.values(person)) console.log(value);
for (const [key, value] of Object.entries(person)) console.log(key, value);

Destructuring#

JavaScript
const [first, second] = fruits;
const [head, ...rest] = fruits;

const { name, age } = person;
const { name: personName } = person;        // rename
const { email = "none" } = person;          // default for missing
const { address: { city } = {} } = person;  // nested, safely

It is used constantly in function parameters:

JavaScript
function describe({ name, age = 0 }) {
  return name + " is " + age;
}

describe({ name: "Ana", age: 34 });

The reference trap#

Objects and arrays are handled by reference. Assigning one to a new variable does not copy it:

JavaScript
const a = { count: 1 };
const b = a;

b.count = 99;
console.log(a.count);     // 99 - the same object

This is the single most common source of “I changed one thing and something else changed too” bugs. To copy:

JavaScript
const copy = { ...a };                 // shallow copy
const arrayCopy = [...fruits];
const merged = { ...defaults, ...userSettings };

But a shallow copy only copies one level. Nested objects are still shared:

JavaScript
const original = { name: "Ana", address: { city: "Leeds" } };
const shallow = { ...original };

shallow.address.city = "York";
console.log(original.address.city);   // York - still shared

const deep = structuredClone(original);   // fully independent

structuredClone is built into modern browsers and Node, and handles dates, maps and sets correctly — unlike the old JSON.parse(JSON.stringify(x)) trick, which silently destroys them.

Comparing#

JavaScript
console.log({ a: 1 } === { a: 1 });   // false - different objects
console.log([1, 2] === [1, 2]);       // false

const x = { a: 1 };
console.log(x === x);                 // true - same reference

Equality compares references, not contents. To compare contents you have to write the comparison yourself, or compare a serialised form for simple flat data.

Nested data#

JavaScript
const orders = [
  { id: 1, customer: { name: "Ana" }, items: ["book", "pen"] },
  { id: 2, customer: { name: "Sam" }, items: ["lamp"] },
];

const names = orders.map(o => o.customer.name);           // ["Ana", "Sam"]
const allItems = orders.flatMap(o => o.items);            // 3 items
const total = orders.reduce((n, o) => n + o.items.length, 0);

const byId = Object.fromEntries(orders.map(o => [o.id, o]));
console.log(byId[2].customer.name);   // Sam

Optional chaining protects against missing levels:

JavaScript
const city = orders[0]?.customer?.address?.city ?? "unknown";

Questions people ask#

Is an array an object?

Technically yes — typeof [] returns “object”. Use Array.isArray(value) to tell them apart reliably.

When should I use a Map instead of an object?

When keys are not strings, when you add and remove entries frequently, or when insertion order matters and keys might look like numbers. For plain configuration and records, an object is simpler.

Why does typeof null return “object”?

A bug in the first version of JavaScript that was never fixed because too much code depends on it. Check for null explicitly with value === null.

What is the difference between undefined and null?

undefined means the value was never set; null means it was deliberately set to nothing. Both are falsy, and ?? treats them the same.

Where to go next#

The JavaScript array methods reference worth bookmarkingRead next

Keep reading

Keep going — pick your next guide

The fastest way to improve is to read one guide, then build the thing it describes. Start with the basics, or jump straight to a project.

Ask a question or share what worked

Your email address will not be published. Required fields are marked *